Questo perché quando si scrive
var foo = {};
foo.x = foo = {n: b} //a=b=c
durante l'esecuzione della linea, foo sta puntando a {}
ma quando questa affermazione è ripartito per riferimento
foo.x = (foo = {n: b}) /a=(b=c)
di foo è cambiato da {}
a {n:b}
ma foo
in foo.x
(a) indica ancora il vecchio riferimento di foo
dal l'espressione della mano sinistra è stata valutata prima dell'inizio del compito.
Come per la spec
Se LeftHandSideExpression è né un ObjectLiteral né un ArrayLiteral,
a. quindi Lasciare che lref sia il risultato della valutazione di LeftHandSideExpression.
Il che significa che prima della cessione foo.x
era ancora avendo riferimento alla vecchia foo
.
Quindi, se si ottimizzare il vostro esempio un po 'facendo
var foo = {z:2};
foo.x = foo.n = {n: 1};
In questo esempio, tu non cambiare il riferimento al foo
, solo assegnato nuova proprietà, quindi l'uscita è ora
oggetto {z: 2, n: oggetto, x: Object}
Ora, ha mantenuto il riferimento alla vecchia foo
poiché un nuovo riferimento non è stato assegnato alcunché quindi tutte le proprietà z
, n
e x
vengono mantenute.
console.log (foo.x) dovrebbe stampare la stessa cosa. – HopefullyHelpful
Ho ricevuto un errore "Impossibile impostare la proprietà 'x' di undefined" –
Non vedo come la prima riga potrebbe funzionare a meno che 'foo' fosse * già * facendo riferimento a qualche oggetto. (E lo stesso vale per il secondo, anche se intuitivamente il secondo "sente" come dovrebbe funzionare così com'è). – nnnnnn