1. delete演算子の特徴
- 文ではなく演算子(式中で使える)
- 削除できるのは"オブジェクトのプロパティ"だけ
- 変数や関数、組み込みプロパティを削除することはできない
- 参照先のデータ自体は削除されない
2. delete演算子で削除できるのはオブジェクトのプロパティ
オブジェクトのプロパティだけを削除することができる
var my_obj = {};
my_obj.a = "test 3";
delete my_obj.a;
my_obj.a; // undefined
my_obj.b = function() { return "test 4"; };
delete my_obj.b;
my_obj.b(); // Error!!
変数や関数、組み込みプロパティは削除できない
StrictモードではSyntax Errorとして扱われる。
var x = "test 1";
delete x; // false, 削除できない
x; // "test 1"
function y() {
return "test 2";
}
delete y; // false, 宣言された関数は削除できない
y(); // "test 2"
var list = [ 1, 2, 3, 4, 5 ];
list; // [ 1, 2, 3, 4, 5 ]
list.length; // 5
delete list.length; // false, 組み込みオブジェクトのプロパティは削除できない
list; // [ 1, 2, 3, 4, 5 ]
list.length; // 5
3. 特殊なケース
var GLOBAL_OBJECT = window;
(function() {
GLOBAL_OBJECT.x = "test 4";
x; // "test 4", スコープチェーンにより上の式で設定した x になる
delete x; // true, 削除できる
// 1つでも同じ変数名を宣言したvar文があると、削除できなくなる。
GLOBAL_OBJECT.y = "test 5";
y; // undefined
delete y; // false, 前後関係なく宣言した変数が優先されるため削除できない
GLOBAL_OBJECT.y; // "test 5"
var y = "test 6";
y; // "test 6"
delete y; // false
delete GLOBAL_OBJECT.y; // true
GLOBAL_OBJECT.y; // undefined
})();
var文で宣言した変数は、関数が実行される直前にundefinedとして初期化されているため、グローバルオブジェクトに設定した名前ではなく宣言した変数が優先される。
4. 参照先のデータ自体は削除されない
var my_obj = {};
my_obj.a = [ 't', 'e', 's', 't' ];
my_obj.b = my_obj.a; // my_obj.aとmy_obj.bは同じデータを参照している
my_obj.a; // [ 't', 'e', 's', 't' ]
my_obj.b; // [ 't', 'e', 's', 't' ]
my_obj.a.push('2'); // '2'を追加
my_obj.a; // [ 't', 'e', 's', 't', '2' ]
my_obj.b; // [ 't', 'e', 's', 't', '2' ], 同じデータを参照しているので反映される
// my_obj.aを削除しても参照していたデータは残っている
delete my_obj.a;
my_obj.a; // undefined
my_obj.b; // [ 't', 'e', 's', 't', '2' ]
delete my_obj.b;
my_obj.a; // undefined
my_obj.b; // undefined
どこからも参照されなくなったデータがメモリから削除されるタイミングは、実行環境のガベージコレクションによる。