C'è qualche differenza sostanziale nel fare uno di questi?
delete a.x;
vs
a.x = undefined;
dove
a = {
x: 'boo'
};
si potrebbe dire che sono equivalenti?
(Non sto prendendo in considerazione cose come "V8 like non usano deletemeglio" )
C'è qualche differenza sostanziale nel fare uno di questi?
delete a.x;
vs
a.x = undefined;
dove
a = {
x: 'boo'
};
si potrebbe dire che sono equivalenti?
(Non sto prendendo in considerazione cose come "V8 like non usano deletemeglio" )
Risposte:
Non sono equivalenti. La differenza principale è quella impostazione
a.x = undefined
significa che a.hasOwnProperty("x")tornerà comunque vero, e quindi, apparirà comunque in un for inciclo, e dentroObject.keys()
delete a.x
significa che a.hasOwnProperty("x")restituirà false
Il modo in cui sono uguali è che non è possibile stabilire se esiste una proprietà testando
if (a.x === undefined)
Cosa che non dovresti fare se stai cercando di determinare se esiste una proprietà, dovresti sempre usarla
// If you want inherited properties
if ('x' in a)
// If you don't want inherited properties
if (a.hasOwnProperty('x'))
Seguendo la catena di prototipi (menzionata da zzzzBov ) Calling deleteconsentirà di risalire la catena di prototipi, mentre l'impostazione del valore su indefinito non cercherà la proprietà nei prototipi concatenati 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
Eliminazione delle proprietà ereditate Se la proprietà che si sta tentando di eliminare viene ereditata, deletenon influirà su di essa. Cioè, deleteelimina solo le proprietà dall'oggetto stesso, non le proprietà ereditate.
var obj = {x: "fromPrototype"};
var extended = Object.create(obj);
delete extended.x;
console.log(extended.x); // Still fromPrototype
Pertanto, se è necessario assicurarsi che il valore di un oggetto sia indefinito, deletenon funzionerà quando la proprietà viene ereditata, è necessario impostarlo (sovrascriverlo) undefinedin quel caso. A meno che non venga utilizzato il luogo che lo sta controllando hasOwnProperty, ma probabilmente non sarebbe sicuro presumere che verrà utilizzato dappertuttohasOwnProperty
"x" in atornerà anche truecon il primo e falsecon il secondo. Anche l'output di Object.keyssarà diverso.
undefined, puoi anche controllare if (a.x), a meno che non sia per numeri e 0 è valido
Per parafrasare la domanda:
Sono
delete a.xeda.x = undefinedequivalenti?
Il primo rimuove la chiave dalla variabile, il successivo imposta la chiave con un valore di undefined. Questo fa la differenza quando si ripetono le proprietà degli oggetti e quando hasOwnPropertyviene utilizzato.
a = {
x: true
};
a.x = undefined;
a.hasOwnProperty('x'); //true
delete a.x;
a.hasOwnProperty('x'); //false
Inoltre, ciò farà una differenza significativa quando è coinvolta la catena di prototipi.
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'
deletepermettergli di salire sulla catena del prototipo
Sì, c'è differenza. Se usi delete a.xx non è più una proprietà di a, ma se la usi a.x=undefinedè una proprietà ma il suo valore non è definito.
I nomi sono un po 'confusi. a.x = undefinedimposta semplicemente la proprietà su undefined, ma la proprietà è ancora lì:
> var a = {x: 3};
> a.x = undefined;
> a.constructor.keys(a)
["x"]
delete lo elimina effettivamente:
> var a = {x: 3};
> delete a.x;
> a.constructor.keys(a)
[]
Questo REPL dal nodo dovrebbe illustrare la differenza.
> 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
Sono sicuro che puoi vedere la differenza tra var o1 = {p:undefined};e var o2 = {};.
In entrambi i casi, o.psarà , undefinedma nel primo caso, è perché quello è il valore e nel secondo caso perché non c'è valore .
deleteè l'operatore che consente di ottenere da o1(o un altro oggetto che ha un valore assegnato alla sua pproprietà) a o2quel modo: delete o1.p;.
L'operazione inversa viene eseguita semplicemente assegnando un valore ( undefinedin questo esempio ma potrebbe essere qualcos'altro) alla proprietà o1.p = undefined;.
Quindi no , non sono equivalenti.
delete o.p; volere
rimuovere la proprietà pdall'oggetto se ne ha uno
non fare diversamente
o.p = undefined; volere
aggiungi una proprietà pall'oggetto se non ne ha ancora una e imposta il suo valore suundefined
cambia semplicemente il valore della proprietà se l'oggetto lo possiede già
Dal punto di vista delle prestazioni, deleteè un problema perché modifica la struttura dell'oggetto (proprio come aggiungere una nuova proprietà se non è stata inizializzata nel costruttore).
Mentre si imposta il valore per undefinedrilasciare anche il contenuto, ma senza forzare la modifica della struttura.
L'oggetto è semplicemente una rappresentazione ad albero, ciò significa che in memoria la radice punta a varie posizioni di memoria in cui sono memorizzate le chiavi di quell'oggetto. e tale posizione punta a un'altra posizione in cui è archiviato il valore effettivo di quella chiave o posizioni in cui sono memorizzate le chiavi figlio o posizioni in cui sono memorizzati i valori dell'array.
Quando si elimina una chiave da un oggetto utilizzando Elimina, in realtà elimina il collegamento tra quella chiave e l'oggetto principale e le posizioni di memoria della chiave e il suo valore vengono liberati per memorizzare un'altra informazione.
Quando si tenta di eliminare qualsiasi chiave impostando undefined come valore, quindi si sta semplicemente impostando il suo valore, non eliminando quella chiave. Ciò significa che la posizione della memoria delle chiavi è ancora collegata al suo oggetto padre e al valore se la chiave non è definita.
L'utilizzo di undefined anziché dell'eliminazione della parola chiave è una pratica errata, in quanto non rilascia la posizione di memoria di quella chiave.
Anche se la chiave non è presente e la si imposta come non definita, tale chiave verrà creata con valore undefined.
per esempio
var a = {};
a.d = undefined;
console.log(a); // this will print { d: undefined }
l'eliminazione non può essere eseguita con le proprietà ereditate perché quella proprietà non fa parte dell'oggetto figlio.
as a general rule of thumb, using 'delete' makes thing slower.e 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. e infine smashingmagazine.com/2012/11/…
Usando un array, invece di un oggetto, posso mostrare che delete usa meno memoria heap di non definita.
Ad esempio, questo codice non finirà:
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);
Produce questo errore:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.
Quindi, come puoi vedere, undefinedoccupa effettivamente memoria heap.
Tuttavia, se hai anche deletel'oggetto ary (invece di impostarlo su undefined), il codice finirà lentamente:
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}.`);
Questi sono esempi estremi, ma sottolineano deleteche non ho visto nessuno menzionare da nessuna parte.