Revision 423237 of delete

  • リビジョンの URL スラグ: Web/JavaScript/Reference/Operators/delete
  • リビジョンのタイトル: delete
  • リビジョンの ID: 423237
  • 作成日:
  • 作成者: ethertank
  • 現行リビジョン いいえ
  • コメント JavaScript/Reference/Operators/delete Web/JavaScript/Reference/Operators/delete
タグ: 

このリビジョンの内容

概要

delete 演算子は、オブジェクトからプロパティを削除します。

Operator
Implemented in: JavaScript 1.2
ECMAScript Edition: ECMA-262 1st Edition

構文

delete expression

expression には、プロパティへの参照になる式を置きます。例えば:

delete variableName
delete objectExpression.property
delete objectExpression["property"]
delete objectExpression[index]
delete property // with 文の内部でのみ有効

expression がプロパティではない場合、delete は何も行いません。

引数

objectName
オブジェクト名です。
property
削除するプロパティです。
index
削除する配列の添字を表す整数です。

戻り値

プロパティは存在するが削除できない場合にのみ、false が返ります。その他の場合すべてで true が返ります。

説明

前出のうち 5 番目の形式は with 文の内部でのみ、オブジェクトからプロパティを削除する方法として有効です。

delete 演算子は暗黙的に宣言された変数を削除することができますが、var あるいは function 文で宣言された変数は削除できません。

delete 演算が成功すると、オブジェクトのプロトタイプに同様の名前のプロパティがあるかもしれないのにもかかわらず、オブジェクトから当該プロパティが完全に削除されます。

一部のオブジェクトプロパティは削除できません。ECMA 262 仕様ではそれらを DontDelete と記しています。

x = 42;        // グローバルオブジェクトのプロパティとして割り当て
var y = 43;    // 変数として定義
myobj = new Number();
myobj.h = 4;    // プロパティ h を作成
myobj.k = 5;    // プロパティ k を作成

delete x;       // true が返る (暗黙的に定義された場合は削除可)
delete y;       // false が返る (var で定義された場合は削除不可、プロパティが DontDelete です)
delete Math.PI; // false が返る (ほとんどの定義済みプロパティは削除不可、DontDelete と定義されています)
delete myobj.h; // true が返る (ユーザ定義のプロパティは削除可)
with(myobj) { 
  delete k;    // true が返る (delete myobj.k と同じ)
} 
delete myobj;   // true が返る (暗黙的に定義された場合は削除可、x と同じ)

プロトタイプから継承してオブジェクトに存在するプロパティは (プロトタイプ上では直接削除可能であるにもかかわらず)、削除できません。

 function Foo(){}
 Foo.prototype.bar = 42;
 var foo = new Foo();
 delete foo.bar;           // しかし、何も行われません
 alert(foo.bar);           // 42 と表示、プロパティは継承されたものです
 delete Foo.prototype.bar; // プロトタイプ上でプロパティを削除
 alert(foo.bar);           // "undefined" と表示、もはやプロパティは継承されません

配列の要素の削除

配列の要素を削除する際、配列の長さは影響を受けません。例えば a{{ mediawiki.external(3) }} を削除しても、a{{ mediawiki.external(4) }} は依然 a{{ mediawiki.external(4) }} であり、a{{ mediawiki.external(3) }} は undefined になります。これは配列の最後の要素を削除した場合 (delete a{{ mediawiki.external('a.length-1') }}) でも維持されます。

delete 演算子で配列の要素を削除すると、その要素は配列の一部ではなくなります。以下の例では trees{{ mediawiki.external(3) }} が delete で削除されています。

var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
   // この部分は実行されません
}

配列の要素が存在する状態にしたいが値は未定義にしたい場合は、delete 演算子に代わり undefined 値を用いてください。以下の例では trees{{ mediawiki.external(3) }} に undefined を代入しており、配列の要素は存在し続けます:

var trees = ["redwood","bay","cedar","oak","maple"];
trees[3]=undefined;
if (3 in trees) {
   // この部分は実行されます
}

クロスブラウザの問題点

ECMAScript はオブジェクトのイテレーション順を実装系依存であるとしているにもかかわらず、すべての主要なブラウザはイテレーション順を、(少なくともプロトタイプ上にないプロパティについて) 最初に追加されたプロパティを最初に持ち出す方式に基づいてサポートしているように見受けられます。ところが Internet Explorer ではプロパティに対して delete を用いたときに、他のブラウザが単純なオブジェクトを整列された連想配列のように用いることを妨げる、ややこしい動作になる場合があります。Internet Explorer では、プロパティのが実際 undefined に設定されているとき、後から同じ名前で再びプロパティを追加すると、そのプロパティは元の場所でイテレートされるようになるでしょう。削除済みのプロパティを再度追加した場合に期待するであろう、イテレーション順の最後ではありません。

よって、クロスブラウザ環境で整列された連想配列をシミュレートしたい場合は、配列を 2 つ (片方はキー、もう片方は値) に分けて用いるか、プロパティをひとつ持つオブジェクトの配列の構築などを強いられます。

このリビジョンのソースコード

<h2 id="Summary">概要</h2>
<p><code>delete</code> 演算子は、オブジェクトからプロパティを削除します。</p>
<table class="standard-table">
  <thead>
    <tr>
      <th class="header" colspan="2" scope="row">Operator</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Implemented in:</td>
      <td>JavaScript 1.2</td>
    </tr>
    <tr>
      <td>ECMAScript Edition:</td>
      <td>ECMA-262 1st Edition</td>
    </tr>
  </tbody>
</table>
<h2 id="Syntax">構文</h2>
<p><code>delete <em>expression</em></code></p>
<p><em>expression</em> には、プロパティへの参照になる式を置きます。例えば:</p>
<pre class="eval">
delete <em>variableName</em>
delete <em>objectExpression.property</em>
delete <em>objectExpression</em>["<em>property</em>"]
delete <em>objectExpression</em>[<em>index</em>]
delete <em>property</em> // with 文の内部でのみ有効
</pre>
<p><em>expression</em> がプロパティではない場合、<code>delete</code> は何も行いません。</p>
<h3 id="Parameters">引数</h3>
<dl>
  <dt>
    <code>objectName</code></dt>
  <dd>
    オブジェクト名です。</dd>
</dl>
<dl>
  <dt>
    <code>property</code></dt>
  <dd>
    削除するプロパティです。</dd>
</dl>
<dl>
  <dt>
    <code>index</code></dt>
  <dd>
    削除する配列の添字を表す整数です。</dd>
</dl>
<h2 id="Returns">戻り値</h2>
<p>プロパティは存在するが削除できない場合にのみ、false が返ります。その他の場合すべてで true が返ります。</p>
<h2 id="Description">説明</h2>
<p>前出のうち 5 番目の形式は <code>with</code> 文の内部でのみ、オブジェクトからプロパティを削除する方法として有効です。</p>
<p><code>delete</code> 演算子は暗黙的に宣言された変数を削除することができますが、<code>var</code> あるいは <code>function</code> 文で宣言された変数は削除できません。</p>
<p><code>delete</code> 演算が成功すると、オブジェクトのプロトタイプに同様の名前のプロパティがあるかもしれないのにもかかわらず、オブジェクトから当該プロパティが完全に削除されます。</p>
<p>一部のオブジェクトプロパティは削除できません。ECMA 262 仕様ではそれらを <em>DontDelete</em> と記しています。</p>
<pre class="brush: js">
x = 42;        // グローバルオブジェクトのプロパティとして割り当て
var y = 43;    // 変数として定義
myobj = new Number();
myobj.h = 4;    // プロパティ h を作成
myobj.k = 5;    // プロパティ k を作成

delete x;       // true が返る (暗黙的に定義された場合は削除可)
delete y;       // false が返る (var で定義された場合は削除不可、プロパティが DontDelete です)
delete Math.PI; // false が返る (ほとんどの定義済みプロパティは削除不可、DontDelete と定義されています)
delete myobj.h; // true が返る (ユーザ定義のプロパティは削除可)
with(myobj) { 
  delete k;    // true が返る (delete myobj.k と同じ)
} 
delete myobj;   // true が返る (暗黙的に定義された場合は削除可、x と同じ)
</pre>
<p>プロトタイプから継承してオブジェクトに存在するプロパティは (プロトタイプ上では直接削除可能であるにもかかわらず)、削除できません。</p>
<pre class="brush: js">
 function Foo(){}
 Foo.prototype.bar = 42;
 var foo = new Foo();
 delete foo.bar;           // しかし、何も行われません
 alert(foo.bar);           // 42 と表示、プロパティは継承されたものです
 delete Foo.prototype.bar; // プロトタイプ上でプロパティを削除
 alert(foo.bar);           // "undefined" と表示、もはやプロパティは継承されません
</pre>
<h3 id="Deleting_array_elements">配列の要素の削除</h3>
<p>配列の要素を削除する際、配列の長さは影響を受けません。例えば a{{ mediawiki.external(3) }} を削除しても、a{{ mediawiki.external(4) }} は依然 a{{ mediawiki.external(4) }} であり、a{{ mediawiki.external(3) }} は undefined になります。これは配列の最後の要素を削除した場合 (<code>delete a{{ mediawiki.external('a.length-1') }}</code>) でも維持されます。</p>
<p><code>delete</code> 演算子で配列の要素を削除すると、その要素は配列の一部ではなくなります。以下の例では trees{{ mediawiki.external(3) }} が <code>delete</code> で削除されています。</p>
<pre class="brush: js">
var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
   // この部分は実行されません
}
</pre>
<p>配列の要素が存在する状態にしたいが値は未定義にしたい場合は、<code>delete</code> 演算子に代わり <code>undefined</code> 値を用いてください。以下の例では trees{{ mediawiki.external(3) }} に undefined を代入しており、配列の要素は存在し続けます:</p>
<pre class="brush: js">
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3]=undefined;
if (3 in trees) {
   // この部分は実行されます
}
</pre>
<h2 id="Cross-browser_issues">クロスブラウザの問題点</h2>
<p>ECMAScript はオブジェクトのイテレーション順を実装系依存であるとしているにもかかわらず、すべての主要なブラウザはイテレーション順を、(少なくともプロトタイプ上にないプロパティについて) 最初に追加されたプロパティを最初に持ち出す方式に基づいてサポートしているように見受けられます。ところが Internet Explorer ではプロパティに対して <code>delete</code> を用いたときに、他のブラウザが単純なオブジェクトを整列された連想配列のように用いることを妨げる、ややこしい動作になる場合があります。Internet Explorer では、プロパティの<em>値</em>が実際 undefined に設定されているとき、後から同じ名前で再びプロパティを追加すると、そのプロパティは<em>元の</em>場所でイテレートされるようになるでしょう。削除済みのプロパティを再度追加した場合に期待するであろう、イテレーション順の最後ではありません。</p>
<p>よって、クロスブラウザ環境で整列された連想配列をシミュレートしたい場合は、配列を 2 つ (片方はキー、もう片方は値) に分けて用いるか、プロパティをひとつ持つオブジェクトの配列の構築などを強いられます。</p>
このリビジョンへ戻す