web-dev-qa-db-ja.com

JavaScriptでオブジェクトを削除する

私はJavaScriptのdelete演算子と少し混乱しています。次のコードを見てください。

var obj = {
    helloText: "Hello World!"
};

var foo = obj;

delete obj;

このコードが実行された後、objnullですが、fooは依然としてobjとまったく同じオブジェクトを参照します。このオブジェクトはfooが指しているのと同じオブジェクトだと思います。

delete objを書くと、変数objではなくobjが指していたオブジェクトがメモリから削除されることを私は予想していたので、これは私を混乱させます。

これは、JavaScriptのGarbage Collectorが保持/解放ベースで動作しているためです。オブジェクトを指す変数が他になければ、になりますメモリから削除されますか?

(ところで、私のテストはSafari 4で行われました。)

347
Steve Harrison

Delete演算子は参照のみを削除し、オブジェクト自体は削除しません。オブジェクト自体を削除した場合、C++の削除のように、他の残りの参照がぶら下がっている可能性があります。 (そして、それらのうちの1つにアクセスするとクラッシュするでしょう。それらをすべてnullにするには、削除するときに余分な作業が必要になるか、各オブジェクトごとに余分なメモリが必要になります。)

Javascriptはガベージコレクションされているので、オブジェクト自体を削除する必要はありません。それらを参照する方法がもうなくなったときに削除されます。

オブジェクトへの参照が終了した場合は、そのオブジェクトへの参照を削除すると便利な場合があります。これにより、ガベージコレクタに再利用できるものに関する詳細な情報が提供されるためです。参照がラージオブジェクトへのままであると、プログラムの他の部分が実際にそのオブジェクトを使用していなくても、それが再利用されないことがあります。

437
Jesse Rusak

deleteコマンドは通常の変数には影響せず、プロパティにのみ影響します。 deleteコマンドの後、プロパティの値はnullになりませんが、まったく存在しません。

プロパティがオブジェクト参照の場合、deleteコマンドはプロパティを削除しますが、オブジェクトは削除しません。オブジェクトに他の参照がない場合、ガベージコレクタはそのオブジェクトを処理します。

例:

var x = new Object();
x.y = 42;

alert(x.y); // shows '42'

delete x; // no effect
alert(x.y); // still shows '42'

delete x.y; // deletes the property
alert(x.y); // shows 'undefined'

(Firefoxでテスト済み)

155
Guffa

「暗黙的に宣言された変数」はグローバルオブジェクトのプロパティなので、deleteは他のプロパティと同じように機能します。 varで宣言された変数は破壊されません。

54
Alex

「暗黙のうちに宣言された変数を削除するためにdelete演算子を使用できますが、varステートメントで宣言された変数は削除できません。」

これがリンクです: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

23
David Ackerman

@Guffaの答えに基づいています。私は以下の方法でうまくいくことがわかりました。

var obj = {
    helloText: "Hello World!"
};

obj = null;

delete obj;

最初にobjをnullに設定することで、それへの参照をすべて削除してから、それを完全に削除できます。

私は他のブラウザでそれをテストしませんでした、しかしこれはphonegap 1.7.0で動きます

6
Bohr

deleteは、Java Scriptでオブジェクトを削除するためには使用されません。

あなたのケースでobject keyを削除するために使用されるdelete

var obj = { helloText: "Hello World!" }; 
var foo = obj;
delete obj;

オブジェクトは削除されませんチェックobjはまだ同じ値を取ります使用方法を削除します。

delete obj.helloText

そしてobj, fooをチェックしてください。両方とも空のオブジェクトです。

4
Umair Ahmed

GCの質問とは別に、パフォーマンスのためには、ブラウザがバックグラウンドで行っている可能性がある最適化を考慮する必要があります - >

http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/

Chromeが使用する舞台裏の「クラス」を変更する可能性があるため、参照を削除するよりも参照を無効にする方が良い場合があります。

2
sksizer

jsperf が見つかりました。この点を考慮すると興味深いと思います。 (絵を完成させるためにそれを周りに保つのは便利かもしれません)

削除 、設定 null 、設定 未定義 を比較します。

ただし、プロパティを何度も削除または設定した場合は、このケースがテストされることに注意してください。

2
garek

IE 5から8までは、Hostオブジェクトのプロパティ(Window、Global、DOMなど)に対してdeleteを使用するとTypeErrorが「オブジェクトはこのアクションをサポートしていません」とスローされるというバグがあります。

var el=document.getElementById("anElementId");
el.foo = {bar:"baz"};
try{
    delete el.foo;
}catch(){
    //alert("Curses, drats and double double damn!");
    el.foo=undefined; // a work around
}

el.foo !== undefinedはIEでは常にtrueを返すので、後でプロパティが完全な値を持つ場所を確認する必要がある場合は"foo" in elを使用してください。

あなたが本当に消えるために本当に財産が必要な場合は...

function hostProxy(Host){
    if(Host===null || Host===undefined) return Host;
    if(!"_hostProxy" in Host){
       Host._hostproxy={_Host:host,prototype:Host};
    }
    return Host._hostproxy;
}
var el=hostProxy(document.getElementById("anElementId"));
el.foo = {bar:"baz"};

delete el.foo; // removing property if a non-Host object

host apiと共にHostオブジェクトを使用する必要がある場合は...

el.parent.removeChild(el._Host);
1
johndhutcheson

私はこれと同じ答えを探すためにこの記事に出くわした。私がやってしまったのは、自分のオブジェクトに保存されているすべての値/オブジェクトをobj.pop()ポップアウトすることです。これが悪い習慣であるかどうかわからない。この手法は、Chrome DevツールまたはFireFox Webコンソールでコードをテストするのに役立ちました。

1
Craig London

変数をnullに設定すると、DOM要素とJavascriptスコープ間で行われる循環参照を含め、すべてのブラウザ内のオブジェクトへの参照を確実に解除できます。 deleteコマンドを使用して、次回のガベージコレクションの実行時にオブジェクトをクリアするようにマークしていますが、同じオブジェクトを参照する変数が複数ある場合、単一の変数を削除するとオブジェクトは解放されず、その変数間のリンクは解除されます。そしてオブジェクト。そして次回のガベージコレクションの実行時には、変数だけが消去されます。

0
Pedro Justo

これは私にとってはうまくいきますが、それは良い習慣ではありません。オブジェクトが属するすべての関連要素を削除するだけです。

 for (element in homeService) {
          delete homeService[element];
0
vineet sagar