2016-06-24 10 views
15

Questo è relativo a Javascript a=b=c statements.Come funziona a.x = a = {n: b} in JavaScript?

Capisco che

foo = foo.x = {n: b}; // console.log(foo) => {n: b} 

ma

foo.x = foo = {n: b}; // console.log(foo) => {n: b} 

Si dovrebbe essere pari a:

foo = {n: b}; 
foo.x = foo; // console.log(foo) => {n: b, x:object} 

mi manca qualcosa qui?

+0

console.log (foo.x) dovrebbe stampare la stessa cosa. – HopefullyHelpful

+0

Ho ricevuto un errore "Impossibile impostare la proprietà 'x' di undefined" –

+0

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

risposta

7

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

  1. 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.

6

E 'uguale

let tmp = foo; 
foo = {n: b}; 
tmp.x = foo; 

Si vedeva, quel vecchio foo (memorizzato in z in questo esempio) è stato modificato:

> z=foo={}; 
{} 
> foo.x = foo = {n: b}; 
{ n: 10 } 
> foo 
{ n: 10 } 
> z 
{ x: { n: 10 } } 
+0

Le altre risposte descrivono che questo è ciò che sta accadendo, ma un esempio con 'tmp' e' foo' che inizialmente hanno lo stesso oggetto del loro valore lo rende molto più chiaro. –

1

ho capito.

var foo = {}; // now foo is a reference point to object {} 
foo.x = foo = {n:1}; // first foo is refer to a new object {n:1}, then old foo referred object {} set a prop x 

// try this to get what you want 
var foo = foo1 = {}; 
foo.x = foo = {n:1}; 
console.log(foo, foo1) // here foo1 is what you want 
18

Con:

foo.x = foo = {n: b}; 

Il principale foo.x è parzialmente valutata per prima, sufficiente a determinare l'esatta destinazione per l'assegnazione, prima di procedere ad assegnare realtà.

Si comporta più lungo le linee di:

var oldFoo = foo; 
foo = {n: b}; 
oldFoo.x = foo; 

This is mentioned in the standard. Il lato sinistro della = viene valutata (1.a) prima che il valore di collocarvi (1.f):

AssignmentExpression: LeftHandSideExpression = AssignmentExpression

1) Se LeftHandSideExpression è né un ObjectLiteralArrayLiteral, quindi
a) Lasciare lref essere il risultato della valutazione LeftHandSideExpression.
...
f) Eseguire? PutValue (lref, rval).

Problemi correlati