概要

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 つ (片方はキー、もう片方は値) に分けて用いるか、プロパティをひとつ持つオブジェクトの配列の構築などを強いられます。

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: fuwafuwafuwa, jungjoo, teoli, ethertank, yyss
 最終更新者: fuwafuwafuwa,