2013-04-16 29 views
22

Perché l'istruzione di assegnazione regolare (per esempio, x = 5) restituire il valore assegnato (5 in questo caso), mentre l'assegnazione combinato con una dichiarazione di variabile (var x = 5) restituisce undefined?valore restituito dalla assegnazione

ho ottenuto i valori di ritorno eseguendo queste dichiarazioni nella console JavaScript del browser Chrome:

> var x = 5; 
undefined 
> y = 5; 
5 
+0

possibile duplicato di [Differenza tra l'utilizzo di var e non l'utilizzo di var in JavaScript] (http://stackoverflow.com/questions/1470488/difference-between-using-var-and-not-using-var-in-javascript). Dai un'occhiata alla risposta di kangax. "' var x = 1' dichiara la variabile 'x' nell'attuale scope (noto anche come contesto di esecuzione) ....' x = 1', d'altra parte, è semplicemente un assegnamento di proprietà, ma prima cerca di risolvere 'x' contro scope chain.Se lo trova ovunque in quella catena di scope, esegue un assegnamento, se non trova 'x', solo allora crea la proprietà' x' su un oggetto globale. " – Chase

+1

che interessante .. Non l'ho mai notato! – anthonybell

+2

Penso che 'x = 5' sia un'espressione in grado di restituire un valore, mentre' var x = 5' è un'asserzione che non lo è. Ciò è più evidente dal fatto che non è possibile dichiarare variabili in linea, cioè 'console.log (var x = 5)'. Da dove ottieni il valore di ritorno di "non definito"? –

risposta

19

Questo è il modo in cui è stato progettato il linguaggio. È coerente con la maggior parte delle lingue.

Avere una dichiarazione variabile restituisce qualcosa di diverso da undefined non ha senso, perché non è possibile utilizzare la parola chiave var in un contesto di espressione.

Avere assegnazione essere un non expression un statement è utile quando si desidera impostare molti variabile per lo stesso valore in una sola volta:

x = y = z = 2; 

Esso può essere utilizzato anche in questo modo:

x = 2*(y = z); // Set y = z, and x = 2*z 

Tuttavia questo non è il codice più leggibile e probabilmente sarebbe meglio scrivere come:

y = z; 
x = 2*z; 
+1

Cosa si interromperebbe se Javascript trattasse una dichiarazione di variabile come espressione (utilizzabile all'interno di altre espressioni, ecc.)? – user10165

+0

@ user10165 Avrebbero dovuto definire più regole e, ad esempio, a che punto dell'espressione è la variabile utilizzabile. Anche in questo caso non ci sono molti casi d'uso, dal momento che puoi fare tutto senza di esso. – Paulpro

+0

completamente d'accordo che è "non il codice più leggibile" – rlesias

1

quando si scrive var x = 5; dichiara x e initalizes il suo valore a 5.

Questo è un VariableStatement, non restituisce nulla,

ma x=5 è un expression che assegna da 5 a x. in quanto non esiste x, JavaScript crea implicitamente un x globale nel codice normale

+0

qual è l'altra x = 5? – anthonybell

+1

È un'operazione di assegnazione. –

+0

Credo che 'x = 5' con nessun'altra qualifica sia equivalente a' window.x = 5', o qualunque sia l'oggetto globale. –

1

Ho modificato la mia risposta a causa di commenti e altre risposte.

L'operatore di assegnazione non restituisce nulla ... Nell'esempio seguente, la prima cosa che fa il parser JS è assegnare da 5 a y. La seconda cosa è assegnare y a x, e così via. L'assegnazione non è return (non è una funzione, e in JS non ha la sintassi C++ per sovraccaricare il comportamento dell'operatore). return è più complesso del compito. Il costrutto return non restituisce solo un valore, ma sta chiudendo il contesto corrente causandone la distruzione. Inoltre sta chiudendo qualsiasi contesto genitore (schema di chiusura) se non ci sono altri bambini che lo usano. Quindi, per favore, NON dirmi (nei commenti) che l'operatore di assegnazione restituisca alcun valore. L'operatore di assegnazione in caso di JS è solo un costrutto linguistico.

Questo costrutto del linguaggio è utile in catene (ed è per questo che tutti parlano di ritorno):

a = x = y = 5; 

Qualsiasi variabile non dichiarata è dichiarata automaticamente dal parser in ambito globale.Se si dichiara variabile in modo esplicito, allora non si può allo stesso tempo utilizzare in catena, in questo modo:

a = var x = y = 5; 

L'uso corretto del codice di cui sopra sarebbe:

var x = y = 5; 
a = x; 

Naturalmente è possibile utilizzare parentesi, per rendere più chiaro il tuo codice, ma ciò non significa che il codice si comporti come una funzione.

Anche l'esempio funziona solo con la console JS, che non viene restituita, ma stampando il risultato di istruzioni o espressioni. Significa che la console JS considera il risultato della dichiarazione della variabile come undefined (uguale alla creazione della funzione: function a() {}).

+0

ritorno? veramente? – Karol

+1

È necessario utilizzare la parentesi poiché l'operatore di assegnazione è il 14 (prossimo all'ultimo) nell'ordine delle operazioni.http: //arguments.callee.info/2008/11/03/order-of-operations-in-javascript/ Tuttavia, dire che un'espressione restituisce un valore è completamente errato. Le espressioni valutano un valore. Sei assolutamente corretto al 100%. – orb

+1

Grazie. Forse sarebbe meno confusionario per un novizio se la console javascript non considerasse il risultato di un'istruzione come "non definita" (poiché da nessuna parte nella lingua si dice così). Invece, avrebbe dovuto semplicemente stampare nulla dopo un'istruzione e il valore di un'espressione dopo un'espressione. – user10165

4

Questo perché var x = 5; è un'istruzione variabile, non un'espressione.

Il comportamento di questa dichiarazione è descritto in Section 12.2 of the ECMAScript Language Reference.

  1. Valutare VariableDeclarationList.
  2. Ritorno (normale, vuoto, vuoto).

Questo è fondamentalmente un valore di void di ritorno.

+1

Grazie per il riferimento. – user10165

+0

@ user10165 Fondamentalmente come è stato progettato il linguaggio, e vedendo come si possono avere più dichiarazioni in una singola istruzione, posso immaginare perché lo hanno reso 'void' :) –

1

L'operatore di assegnazione (ovvero il segno di uguale) (1) assegna l'operando di destra (cioè un valore o il valore di una variabile, una proprietà o una funzione) all'operando di sinistra (cioè , variabile o proprietà) e quindi (2) l'espressione di assegnazione (ad esempio, y = 10) diventa un semplice operando con lo stesso valore del suo operando di destra (ad es. 10) prima di valutare il resto dell'espressione. Questo è simile a quando una funzione chiamata viene sostituito con il valore di ritorno quando un'espressione viene valutata (anche chiamate di funzione sono primo nell'ordine delle operazioni e le operazioni di assegnazione sono XIV):

var x, y, z = 1; 
x = z + (y = 2); // x === 3  

function returnTwo() { 
    return 2; 
} 

x = z + returnTwo(); // x === 3 

Si precisa che non solo x ora è uguale a 3, ma l'intera espressione è pari a 3.

Lo scopo della parola chiave var è di associare le variabili allo scope corrente. Le variabili dichiarate con la parola chiave var sono associate all'ambito in cui sono dichiarate. Il var parola assegna il più a sinistra variabile (o struttura) come riferimento al valore dell'espressione valutata:

var fun = function() { 
    var x = 1; 
    var y = x + 1; 
    return y; 
} 

// The x and y variables are bound to the scope of the fun function. 

Uso della parola var con un'espressione è chiamato una dichiarazione. Le dichiarazioni sono azioni che non valutano un valore, nemmeno non definito (anche se la tua console sta stampando indefinito). Inoltre, le dichiarazioni non possono apparire dove JavaScript si aspetta un'espressione, come hanno mostrato altre risposte a questo post.

+0

" La parola chiave var è un operatore speciale che scrive il valore di ritorno di una dichiarazione alla memoria "Quindi se non si ha' var' allora il valore di ritorno dell'istruzione non viene scritto in memoria? – Karol

+0

Sì, è meglio che lo regoli. – orb

+0

Grazie per l'aiuto. A volte pensieri casuali sul modo in cui Java si insinua nella mia testa quando ho a che fare con JavaScript e finisco per dovermi schiaffeggiare la testa un paio di volte. – orb