2010-08-02 3 views
24

Je ne suis pas nouveau à JS ou sa syntaxe, mais parfois, la sémantique de la langue m'a parfois bloqué. Au travail aujourd'hui, un collègue a mentionné ceci:En JavaScript, l'attribution enchaînée est-elle correcte?

var a = b = []; 

n'est pas la même chose que

var a = [], b = []; 

ou

var a = []; var b = []; 

depuis la première version attribue en fait la référence à un tableau vide à un et B. Je ne pouvais pas vraiment accepter cela comme vrai, mais je ne suis pas sûr. Qu'est-ce que vous en pensez tous?

+3

Voir http://stackoverflow.com/questions/1758576/multiple-left-hand-assignment-with-javascript/1758912 # 1758912 –

+0

Merci, Crescent Fresh - Je n'ai pas vraiment vu cette question parce que je cherchais une "affectation chaînée". – JamieJag

Répondre

32

Oui, ils ne sont pas les mêmes. var a = b = [] est équivalent à

var a; 
b = []; 
a = b; 

Non seulement les deux a et b obtenir attribué la même valeur (une référence au même tableau vide), b n'est pas déclaré du tout. Dans strict mode dans ECMAScript 5 et versions ultérieures, ceci lancera un ReferenceError; sinon, à moins qu'il n'y ait déjà une variable b dans la portée, b est créée silencieusement en tant que propriété de l'objet global et agit de manière similaire à une variable globale, quel que soit le code, même à l'intérieur d'une fonction. Ce qui n'est pas bon.

Vous pouvez voir assez facilement:

(function() { 
    var a = b = []; 
})(); 

window.console.log(b); // Shows [] 
+1

Je n'ai pas vu immédiatement que b était une variable globale, merci! – JamieJag

+4

+1 Une autre raison pour éviter une affectation à une référence non résolue est que sur ES5, en mode strict, un 'ReferenceError' sera lancé. – CMS

4

Votre collègue a raison. La première instruction crée un nouveau tableau vide. Ensuite, une référence à ce tableau est assignée à b. Ensuite, la même référence (qui est le résultat de l'expression d'affectation) est affectée à a. Donc a et b se réfèrent au même tableau.

Dans tous les autres cas, vous créez deux tableaux individuels. A propos: Ce comportement est assez commun et est le même dans tous les langages de programmation basés sur C. Donc, ce n'est pas spécifique à JavaScript.

+0

Merci pour votre réponse, Tobias, et pour avoir souligné les points communs dans toutes les langues basées sur C. – JamieJag

+0

Ceci peut être testé avec des tableaux dans JS: '[" dog "] === [" dog "];' renvoie false, mais 'var a = b = [" dog "]; a === b; 'retourne vrai. – b00t

9

Votre collègue a raison:

var a = b = []; 
a.push('something'); 
console.log(b);   // outputs ["something"] 

mais:

var a = [], b = []; 
a.push('something'); 
console.log(b);   // outputs [] 
3

Avec le premier exemple b est une référence à a et b devient une variable globale, accessible de partout (et il remplace toute variable b qui peut déjà exister dans le périmètre global).

0

Pour compléter les réponses déjà fournies.missions ref sont différentes des affectations de valeurs

var x = y = 3; // by value 
y++; // 4 
x; // 3 

var a = b = []; // by ref 
b.push(1); // [1]; 
a; // [1] 
a; = []; 
a.push(2); // [2]; 
b; // [1] 

Maintenant que nous avons répondu à 2 deux, votre question fait également référence à effilochage, ce qui est la pratique du « code assez » (non fonctionnel). En fait, JSHint has deprecated all their "pretty code rules"

Cela dit, je l'habitude d'utiliser la style.- suivante

var a, b, c, // first row all unassigned 
    x = 1, // 1 row per assigned 
    y = 2, 
    list = [ 
     'additional', 
     'indentation' 
    ], 
    obj = { 
     A: 'A', 
     B: 'B' 
    }; 
var z = y +2; // created a new `var` cluster since it uses a var from the previous 
Questions connexes