Is er een wezenlijk verschil in het doen van een van beide?
delete a.x;
vs
a.x = undefined;
waar
a = {
x: 'boo'
};
kan men zeggen dat ze gelijkwaardig zijn?
(Ik houd geen rekening met dingen als “V8 gebruikt liever niet delete
better”)
Antwoord 1, autoriteit 100%
Ze zijn niet gelijkwaardig. Het belangrijkste verschil is die instelling
a.x = undefined
betekent dat a.hasOwnProperty("x")
nog steeds true retourneert, en daarom zal het nog steeds verschijnen in een for in
-lus en in Object.keys()
delete a.x
betekent dat a.hasOwnProperty("x")
false retourneert
De manier waarop ze hetzelfde zijn, is dat je niet kunt zien of een eigenschap bestaat door te testen
if (a.x === undefined)
Wat u niet moet doen als u probeert te bepalen of een eigenschap bestaat, u moet altijd
gebruiken
// If you want inherited properties
if ('x' in a)
// If you don't want inherited properties
if (a.hasOwnProperty('x'))
De prototypeketen volgen(vermeld door zzzzBov) Door delete
aan te roepen, kan het omhoog gaan in de prototypeketen, terwijl het instellen van de waarde op undefined niet zal zoeken naar de eigenschap in de geketende prototypes 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
Overgenomen eigenschappen verwijderenAls de eigenschap die u probeert te verwijderen is overgenomen, heeft delete
hier geen invloed op. Dat wil zeggen, delete
verwijdert alleen eigenschappen van het object zelf, geen overgeërfde eigenschappen.
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
delete extended.x;
console.log(extended.x); // Still fromPrototype
Daarom, als u ervoor moet zorgen dat de waarde van een object ongedefinieerd is, zal delete
niet werken wanneer de eigenschap wordt overgenomen, u moet het instellen (overschrijven) op undefined
in dat geval. Tenzij de plaats die ernaar zoekt hasOwnProperty
zal gebruiken, maar het is waarschijnlijk niet veilig om aan te nemen dat overal waar wordt gecontroleerd het hasOwnProperty
zal gebruiken
Antwoord 2, autoriteit 17%
Om de vraag te parafraseren:
Zijn
delete a.x
ena.x = undefined
equivalent?
Nee.
De eerste verwijdert de sleutel uit de variabele, de latere stelt de sleutel in met een waarde van undefined
. Dit maakt een verschil bij het herhalen van eigenschappen van objecten en wanneer hasOwnProperty
wordt gebruikt.
a = {
x: true
};
a.x = undefined;
a.hasOwnProperty('x'); //true
delete a.x;
a.hasOwnProperty('x'); //false
Bovendien zal dit een aanzienlijk verschil maken als het om de prototypeketen gaat.
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'
Antwoord 3, autoriteit 2%
Als a.x
een setter-functie is, roept a.x = undefined
de functie aan, terwijl delete a.x
de functie niet aanroept.
>
Antwoord 4
Ja, er is een verschil.
Als je delete a.x
gebruikt, is de x niet langer een eigenschap van a, maar als je a.x=undefined
gebruikt, is het een eigenschap maar de waarde ervan is niet gedefinieerd.
Antwoord 5
De namen zijn een beetje verwarrend. a.x = undefined
zet de eigenschap gewoon op undefined
, maar de eigenschap is er nog steeds:
> var a = {x: 3};
> a.x = undefined;
> a.constructor.keys(a)
["x"]
delete
verwijdert het daadwerkelijk:
> var a = {x: 3};
> delete a.x;
> a.constructor.keys(a)
[]
Antwoord 6
Deze REPL van node zou het verschil moeten illustreren.
> a={ x: 'foo' };
{ x: 'foo' }
> for (var i in a) { console.log(i); };
x
undefined
> a.x=undefined;
undefined
> for (var i in a) { console.log(i); };
x
undefined
> delete a.x;
true
> for (var i in a) { console.log(i); };
undefined
Antwoord 7
Ik weet zeker dat je het verschil kunt zien tussen var o1 = {p:undefined};
en var o2 = {};
.
In beide gevallen zal o.p
undefined
zijn, maar in het eerste geval is dat omdat dat de waardeis en in het tweede geval omdat er is geen waarde.
delete
is de operator waarmee u van o1
(of een ander object waaraan een waarde is toegewezen aan de eigenschap p
) naar o2
op die manier: delete o1.p;
.
De omgekeerde bewerking wordt uitgevoerd door simpelweg een waarde toe te kennen (undefined
in dit voorbeeld, maar het kan iets anders zijn) aan de eigenschap o1.p = undefined;
.
Dus nee, ze zijn niet gelijkwaardig.
delete o.p;
zal
-
verwijder de eigenschap
p
van het object als het er een heeft -
niets anders doen
o.p = undefined;
zal
-
voeg een eigenschap
p
toe aan het object als het er nog geen heeft en stel de waarde in opundefined
-
wijzig eenvoudig de waarde van de eigenschap als het object deze al heeft
Vanuit prestatieperspectief is delete
slechtomdat het de structuur van het object wijzigt(net als het toevoegen van een nieuwe eigenschap als je niet geïnitialiseerd in de constructor).
Terwijl het instellen van de waarde op undefined
de inhoud ook vrijgeeft, maar zonder de structuur te hoeven wijzigen.
Antwoord 8
Object is gewoon een boomweergave, dat wil zeggen dat in het geheugen de hoofdmap verwijst naar verschillende geheugenlocaties waar de sleutels van dat object zijn opgeslagen. en die locatie verwijst naar een andere locatie waar de werkelijke waarde van die sleutel is opgeslagen, of locaties waar de onderliggende sleutels zijn opgeslagen of locaties waar de array-waarden zijn opgeslagen.
Als je een sleutel van een object verwijdert met delete, wordt de koppeling tussen die sleutel en het bovenliggende object in feite verwijderd en worden de geheugenlocaties van de sleutel en de waarde ervan vrijgemaakt om andere informatie op te slaan.
Als u een sleutel probeert te verwijderen door undefined als waarde in te stellen, dan stelt u alleen de waarde in en verwijdert u die sleutel niet. Dat betekent dat de geheugenlocatie van de sleutel nog steeds is gekoppeld aan het bovenliggende object en de waarde als de sleutel niet is gedefinieerd.
Het gebruik van undefined in plaats van het gebruik van delete-trefwoord is een slechte gewoonte, omdat het de geheugenlocatie van die sleutel niet vrijgeeft.
Zelfs als de sleutel niet aanwezig is en u deze instelt als ongedefinieerd, wordt die sleutel gemaakt met de waarde undefined
.
bijv.
var a = {};
a.d = undefined;
console.log(a); // this will print { d: undefined }
delete kan niet worden gebruikt met overgenomen eigenschappen omdat die eigenschap niet het deel is van dat onderliggende object.
Antwoord 9
Door een array te gebruiken in plaats van een object, kan ik aantonen dat verwijderen minder heapgeheugen gebruikt dan undefined.
Deze code zal bijvoorbeeld niet eindigen:
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);
Het geeft deze fout:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.
Dus, zoals je kunt zien, neemt undefined
eigenlijk heap-geheugen in beslag.
Als u echter ook het ary-item delete
(in plaats van het alleen in te stellen op undefined
), zal de code langzaam eindigen:
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}.`);
Dit zijn extreme voorbeelden, maar ze maken een punt over delete
dat ik nog nergens heb zien noemen.