これらのいずれかを行うことで実質的な違いはありますか?
delete a.x;
対
a.x = undefined;
どこ
a = {
x: 'boo'
};
それらは同等であると言えるでしょうか?
(「V8はdeleteより良く使わないのが好き」などのことは考慮していません)
これらのいずれかを行うことで実質的な違いはありますか?
delete a.x;
対
a.x = undefined;
どこ
a = {
x: 'boo'
};
それらは同等であると言えるでしょうか?
(「V8はdeleteより良く使わないのが好き」などのことは考慮していません)
回答:
それらは同等ではありません。主な違いはその設定です
a.x = undefined
は、a.hasOwnProperty("x")trueを返すことを意味します。したがって、for inループに表示され、Object.keys()
delete a.x
a.hasOwnProperty("x")falseを返すことを意味します
それらが同じである方法は、テストによってプロパティが存在するかどうかを確認できないことです
if (a.x === undefined)
プロパティが存在するかどうかを判断しようとしている場合はすべきではありませんが、常に使用する必要があります
// If you want inherited properties
if ('x' in a)
// If you don't want inherited properties
if (a.hasOwnProperty('x'))
プロトタイプチェーン(zzzzBovで説明)に従うと、プロトタイプチェーンdeleteを上に移動できるようになりますが、値をundefinedに設定すると、チェーンされたプロトタイプhttp://jsfiddle.net/NEEw4/1/でプロパティが検索されません。
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
extended.x = "overriding";
console.log(extended.x); // overriding
extended.x = undefined;
console.log(extended.x); // undefined
delete extended.x;
console.log(extended.x); // fromPrototype
継承されたプロパティの削除削除しようとしているプロパティが継承されている場合、delete影響はありません。つまり、delete継承されたプロパティではなく、オブジェクト自体からプロパティのみを削除します。
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
delete extended.x;
console.log(extended.x); // Still fromPrototype
したがって、オブジェクトの値が未定義でありdelete、プロパティが継承されたときに機能しないことを確認する必要undefinedがある場合は、その場合はそれをに設定(オーバーライド)する必要があります。それをチェックしている場所がを使用しない限り、それhasOwnPropertyをチェックするすべての場所が使用すると想定するのは安全ではないでしょうhasOwnProperty
"x" in atrue前者、そしてfalse後者と共に戻ります。の出力Object.keysも異なります。
undefinedている場合はif (a.x)、それが数値であり、0が有効でない限り、単にチェックすることもできます
質問を言い換えると:
ある
delete a.xとa.x = undefined同等?
前者は変数からキーを削除し、後者はキーに値を設定しますundefined。これは、オブジェクトのプロパティを繰り返し処理する場合と、hasOwnPropertyを使用する場合に違いがあります。
a = {
x: true
};
a.x = undefined;
a.hasOwnProperty('x'); //true
delete a.x;
a.hasOwnProperty('x'); //false
さらに、プロトタイプチェーンが関与している場合、これは大きな違いになります。
function Foo() {
this.x = 'instance';
}
Foo.prototype = {
x: 'prototype'
};
a = new Foo();
console.log(a.x); //'instance'
a.x = undefined;
console.log(a.x); //undefined
delete a.x;
console.log(a.x); //'prototype'
deleteプロトタイプチェーンの上昇を許可することについての素晴らしい点
はい、違いがあります。delete a.xx を使用すると、aのプロパティではなくなりますが、xを使用a.x=undefinedすると、プロパティですが、その値は定義されません。
私はあなたが間の違いを見ることができると確信していvar o1 = {p:undefined};とvar o2 = {};。
どちらの場合も、にo.pなりますundefinedが、前者の場合はそれが値であるため、後者の場合は値がないためです。
deleteあなたから取得することができます演算子であるo1(またはそのに割り当てられている値がある別のオブジェクトpプロパティ)にo2その方法は:delete o1.p;。
逆の操作はundefined、プロパティに値(この例では、何か他のものでもかまいません)を割り当てるだけで行われますo1.p = undefined;。
だから、いいえ、彼らは同じではありません。
delete o.p; 意志
プロパティpがある場合は、オブジェクトからプロパティを削除します
他に何もしない
o.p = undefined; 意志
プロパティpがまだない場合はオブジェクトにプロパティを追加し、その値をundefined
オブジェクトにすでにある場合は、プロパティの値を変更するだけです
パフォーマンスの観点から、deleteある悪いことがあるため、オブジェクトの構造を変更する(ちょうどあなたがコンストラクタでそれを初期化していない場合は、新しいプロパティを追加するなど)。
一方、値を設定するとundefinedコンテンツも解放されますが、構造を強制的に変更する必要はありません。
オブジェクトは単なるツリー表現です。つまり、メモリ内のルートは、そのオブジェクトのキーが格納されているさまざまなメモリの場所を指します。その場所は、そのキーの実際の値が格納されている別の場所、または子キーが格納されている場所、または配列値が格納されている場所を指します。
削除を使用してオブジェクトからキーを削除すると、実際にはそのキーとその親オブジェクトの間のリンクが削除され、キーのメモリ位置とその値が解放されて、別の情報が保存されます。
undefinedを値として設定してキーを削除しようとすると、そのキーを削除するのではなく、単に値を設定しているだけです。つまり、キーのメモリ位置は、その親オブジェクトおよびキーが定義されていない場合の値に引き続きリンクされます。
deleteキーワードを使用する代わりにundefinedを使用することは、そのキーのメモリ位置を解放しないため、お勧めできません。
キーが存在せず、未定義に設定した場合でも、そのキーはvalueで作成されますundefined。
例えば
var a = {};
a.d = undefined;
console.log(a); // this will print { d: undefined }
削除されたプロパティは子オブジェクトの一部ではないため、継承されたプロパティでは削除できません。
as a general rule of thumb, using 'delete' makes thing slower.とdevelopers.google.com/v8/design To reduce the time required to access JavaScript properties, V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes. In V8, an object changes its hidden class when a new property is added.、そして最終的にsmashingmagazine.com/2012/11/...
オブジェクトの代わりに配列を使用して、deleteが未定義よりも少ないヒープメモリを使用することを紹介できます。
たとえば、次のコードは終了しません:
let y = 1;
let ary = [];
console.log("Fatal Error Coming Soon");
while (y < 4294967295)
{
ary.push(y);
ary[y] = undefined;
y += 1;
}
console(ary.length);
このエラーが発生します:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.
ご覧のとおり、undefined実際にはヒープメモリを消費します。
ただし、deleteary-itemも(単にに設定するのではなくundefined)場合、コードはゆっくり終了します。
let x = 1;
let ary = [];
console.log("This will take a while, but it will eventually finish successfully.");
while (x < 4294967295)
{
ary.push(x);
ary[x] = undefined;
delete ary[x];
x += 1;
}
console.log(`Success, array-length: ${ary.length}.`);
これらは極端な例ですが、deleteどこにも言及されている人を見たことがありません。