221 votes

Affectation multiple à gauche avec JavaScript

var var1 = 1,
    var2 = 1,
    var3 = 1;

C'est équivalent à ceci :

var var1 = var2 = var3 = 1;

Je suis presque certain que c'est l'ordre dans lequel les variables sont définies : var3, var2, var1, ce qui serait équivalent à ceci :

var var3 = 1, var2 = var3, var1 = var2;

Existe-t-il un moyen de le confirmer en JavaScript ? En utilisant éventuellement un profileur ?

10 votes

L'AFFECTATION SE FAIT DE DROITE À GAUCHE précédence des opérateurs javascript

1 votes

Cela s'applique-t-il également si j'utilise this.var1 = this.var2 = this.var3 = 1 ?

0 votes

Oui, jusqu'à ce que ce soit une variable globale car this fait référence à l'objet fenêtre.

450voto

Crescent Fresh Points 54070

En fait,

var var1 = 1, var2 = 1, var3 = 1;

est pas équivalent :

var var1 = var2 = var3 = 1;

La différence réside dans le cadrage :

function good() {
  var var1 = 1, var2 = 1, var3 = 1;
}

function bad() {
  var var1 = var2 = var3 = 1;
}

good();
alert(window.var2); // undefined

bad();
alert(window.var2); // 1. Aggh!

En fait, cela montre que les affectations sont associatives à droite. Le site bad est équivalent à l'exemple suivant :

var var1 = (window.var2 = (window.var3 = 1));

54 votes

Dang, c'est inattendu. Merci pour le conseil, je vais faire attention à ça.

3 votes

Je ne comprends pas... pourquoi les variables de bad() seraient-elles en dehors de la portée de la fonction ? Et ne devraient-elles pas être collectées lorsque la fonction est terminée ?

10 votes

@SkinnyG33k parce que c'est de droite à gauche. donc il analysera le plus à droite avant le plus à gauche. donc var var1=var2 se produit après var3 = 1 et après var2 = var3 . c'est comme var3=1; var2=var3; var var1=var2

27voto

Justin Johnson Points 16243

L'affectation en javascript fonctionne de droite à gauche. var var1 = var2 = var3 = 1; .

Si la valeur de l'une de ces variables est 1 après cette déclaration, alors logiquement il doit avoir commencé à partir de la droite, sinon la valeur ou var1 et var2 serait indéfinie.

Bien qu'il ne compile pas, vous pouvez le considérer comme l'équivalent de var (var1 = (var2 = (var3 = 1))); où la série de parenthèses la plus intérieure est évaluée en premier.

1 votes

Merci, ça aide vraiment. Il est utile de penser aux erreurs qui seraient générées si le programme était évalué autrement que de droite à gauche (dans ce cas, l'erreur serait que var1/var2 sont indéfinies).

5 votes

C'est en fait une erreur de syntaxe. Vous ne pouvez pas avoir ( immédiatement après var . La suppression de la série de parenthèses extérieures permet de compiler sans erreur, var var1 = (var2 = (var3 = 1)); . À l'époque, je trouvais que cela n'illustrait pas aussi bien le propos, mais je suppose que c'est la même chose.

0 votes

var var1 = var2 = var3 = 1;. égal à var var3 = 1; var var2 = var3; var var1 = var2;

11voto

Gangadhar Jannu Points 114

var var1 = 1, var2 = 1, var3 = 1 ;

Dans ce cas var Le mot-clé est applicable aux trois variables.

var var1 = 1,
    var2 = 1,
    var3 = 1;

ce qui n'est pas équivalent à ceci :

var var1 = var2 = var3 = 1 ;

Dans ce cas, derrière les écrans var Le mot-clé est uniquement applicable à var1 à cause de la remontée de variable et le reste de l'expression est évalué normalement donc les variables var2, var3 deviennent globaux

Javascript traite ce code dans cet ordre :

/*
var1 is local to the particular scope because of var keyword
var2 and var3 will become globals because they are used without var keyword
*/

var var1;   //only variable declarations will be hoisted.

var1 = var2 = var3 = 1;

9voto

neaumusic Points 407
a = (b = 'string is truthy'); // b gets string; a gets b, which is a primitive (copy)
a = (b = { c: 'yes' }); // they point to the same object; a === b (not a copy)

(a && b) est logiquement (a ? b : a) et se comporte comme une multiplication (ex. !!a * !!b )

(a || b) est logiquement (a ? a : b) et se comporte comme une addition (ex. !!a + !!b )

(a = 0, b) c'est l'abréviation de ne pas se soucier si a est vrai, retourner implicitement b


a = (b = 0) && "nope, but a is 0 and b is 0"; // b is falsey + order of operations
a = (b = "b is this string") && "a gets this string"; // b is truthy + order of ops

Prédominance des opérateurs JavaScript (ordre des opérations)

Notez que l'opérateur virgule est en fait l'opérateur le moins privilégié, mais que les parenthèses sont les plus privilégiées, et qu'elles vont de pair lors de la construction d'expressions d'une ligne.


Au bout du compte, vous aurez peut-être besoin de "thunks" plutôt que de valeurs codées en dur. Pour moi, un thunk est à la fois la fonction et la valeur résultante (la même "chose").

const windowInnerHeight = () => 0.8 * window.innerHeight; // a thunk

windowInnerHeight(); // a thunk

4voto

Joel Coehoorn Points 190579

Essayez ça :

var var1=42;
var var2;

alert(var2 = var1); //show result of assignment expression is assigned value
alert(var2); // show assignment did occur.

Notez le simple '=' dans la première alerte. Cela montre que le résultat d'une expression d'affectation est la valeur affectée, et la deuxième alerte vous montre que l'affectation a bien eu lieu.

Il s'ensuit logiquement que l'affectation doit s'être enchaînée de droite à gauche. Cependant, puisque tout ceci est atomique au javascript (il n'y a pas de threading), un moteur particulier peut choisir de l'optimiser un peu différemment.

1 votes

Merci pour la réponse. Je pense que je cherchais un moyen d'utiliser les alertes tout en conservant la structure d'affectation multiple (a=b=c), mais je ne pense pas que ce soit possible.

1 votes

Les déclarations individuelles comme celle-ci en javascript (et, bien que plusieurs expressions, cela revient à une seule déclaration) peuvent être considérées comme atomiques. Il faut les décomposer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X