概要
delete
演算子は、オブジェクトからプロパティを削除します。
構文
delete expression
expression には、プロパティへの参照になる式を置きます。例えば:
delete object.property delete object['property']
expression がプロパティではない場合、delete
は何も行いません。
引数
object
- オブジェクト名またはオブジェクトとして評価される式
property
- 削除するプロパティです。
index
- 削除する配列の添字を表す整数です。
戻り値
プロパティは存在するが削除できない場合にのみ、false が返ります。その他の場合すべてで true が返ります。
説明
前出のうち 5 番目の形式は with
文の内部でのみ、オブジェクトからプロパティを削除する方法として有効です。
delete
演算子は暗黙的に宣言された変数を削除することができますが、var
あるいは function
文で宣言された変数は削除できません。
delete
演算が成功すると、オブジェクトのプロトタイプに同様の名前のプロパティがあるかもしれないのにもかかわらず、オブジェクトから当該プロパティが完全に削除されます。
一部のオブジェクトプロパティは削除できません(例えば Object, Array, Math など)。ECMAScript 5とその後の仕様では 262 仕様ではそれらをnon-configurableとして記述されています。
一時的デットゾーン(Temporal dead zone)
"temporal dead zone" (TDZ)は const
とletの宣言のため
ECMAScript 6に定義されているし、 delete演算子にも明示されている。従って以下のようなコードは ReferenceError
を投げる。
function foo() {
delete x;
let x;
}
function bar() {
delete y;
const y;
}
例
x = 42; // x プロパティをグローバルオブジェクトに割り当て var y = 43; // y プロパティをグローバルオブジェクトに割り当て、non-configurableにマーキング myobj = { h: 4, k: 5 }; // xは削除できるglobalオブジェクトのプロパティ delete x; // true が返る (暗黙的に定義された場合は削除可) // yはnon-configurableであるため、削除できない delete y; // false が返る (var で定義された場合は削除不可、プロパティが DontDelete です) // deleteは前定義プロパティには影響しない delete Math.PI; // false が返る (ほとんどの定義済みプロパティは削除不可、DontDelete と定義されています) // 使用者定義プロパティは削除できる。 delete myobj.h; // true が返る (ユーザ定義のプロパティは削除可) // myobbはグローバルオブジェクトのプロパティであり、変数ではないので // 削除できる delete myobj; // true が返る (暗黙的に定義された場合は削除可、x と同じ) function f() { var z = 44; // deleteはローカル変数には影響しない delete k; // false が返る }
プロトタイプから継承してオブジェクトに存在するプロパティは (プロトタイプ上では直接削除可能であるにもかかわらず)、削除できません。
function Foo(){} Foo.prototype.bar = 42; var foo = new Foo();
// trueを返却するが、何も行われません // なぜなら、barは継承プロパティだからdelete foo.bar;
// 42 と表示、プロパティは継承されたものです。上で削除されてないから表示される。console.log(foo.bar);
// プロトタイプ上でプロパティを削除delete Foo.prototype.bar;
// "undefined" と表示、もはやプロパティは継承されません。上で削除されたからである。console.log(foo.bar);
配列の要素の削除
配列の要素を削除する際、配列の長さは影響を受けません。例えば a[3] を削除しても、a[4] は依然 a[4] であり、a[3] は undefined になります。これは配列の最後の要素を削除した場合 (delete a[a.length-1]
) でも維持されます。
delete
演算子で配列の要素を削除すると、その要素は配列の一部ではなくなります。以下の例では trees[3] が delete
で削除されています。
var trees = ["redwood","bay","cedar","oak","maple"]; delete trees[3]; if (3 in trees) { // この部分は実行されません }
配列の要素が存在する状態にしたいが値は未定義にしたい場合は、delete
演算子に代わり undefined
値を用いてください。以下の例では trees[3] に undefined を代入しており、配列の要素は存在し続けます:
var trees = ["redwood","bay","cedar","oak","maple"]; trees[3]=undefined; if (3 in trees) { // この部分は実行されます }
クロスブラウザの問題点
ECMAScript はオブジェクトのイテレーション順を実装系依存であるとしているにもかかわらず、すべての主要なブラウザはイテレーション順を、(少なくともプロトタイプ上にないプロパティについて) 最初に追加されたプロパティを最初に持ち出す方式に基づいてサポートしているように見受けられます。ところが Internet Explorer ではプロパティに対して delete
を用いたときに、他のブラウザが単純なオブジェクトを整列された連想配列のように用いることを妨げる、ややこしい動作になる場合があります。Internet Explorer では、プロパティの値が実際 undefined に設定されているとき、後から同じ名前で再びプロパティを追加すると、そのプロパティは元の場所でイテレートされるようになるでしょう。削除済みのプロパティを再度追加した場合に期待するであろう、イテレーション順の最後ではありません。
よって、クロスブラウザ環境で整列された連想配列をシミュレートしたい場合は、配列を 2 つ (片方はキー、もう片方は値) に分けて用いるか、プロパティをひとつ持つオブジェクトの配列の構築などを強いられます。