web-dev-qa-db-fra.com

Affectation multiple à gauche avec JavaScript

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

Ceci 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;

Est-il possible de le confirmer en JavaScript? Vous utilisez éventuellement un profileur?

174
David Calhoun

Réellement,

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

est not équivalent à:

var var1 = var2 = var3 = 1;

La différence est dans la portée:

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

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

good();
console.log(window.var2); // undefined

bad();
console.log(window.var2); // 1. Aggh!

En fait, cela montre que les assignations sont juste associatives. L'exemple bad équivaut à:

var var1 = (window.var2 = (window.var3 = 1));
382
Crescent Fresh

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 instruction, elle doit alors avoir été logiquement partie de la droite, sinon la valeur ou var1 Et var2 Ne serait pas définie.

Vous pouvez le considérer comme équivalent à var var1 = (var2 = (var3 = 1));, où l'ensemble de parenthèses le plus interne est évalué en premier.

17
Justin Johnson
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 (par exemple, !!a * !!b)

(a || b) est logiquement (a ? a : b) et se comporte comme une addition (par exemple, !!a + !!b)

(a = 0, b) est l'abréviation de ne pas se soucier de si a est la vérité, retourne 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

Priorité des opérateurs JavaScript (ordre des opérations)

Notez que l'opérateur de 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 création d'expressions d'une ligne.


Finalement, vous aurez peut-être besoin de "thunks" plutôt que de valeurs codées en dur, et 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
8
neaumusic

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

Dans ce cas, le mot clé var s'applique aux trois variables.

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

qui n'est pas équivalent à ceci:

var var1 = var2 = var3 = 1;

Dans ce cas derrière les écrans, le mot clé var s'applique uniquement à var1 en raison du levage variable et du reste de l’expression est évaluée normalement, ainsi les variables var2, var3 sont en train de devenir globals

Javascript traite ce code dans cet ordre:

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

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

var1= var2= var3 = 1; 
7
Gangadhar Jannu

Essaye ç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 montrera que le résultat d'une expression d'affectation est la valeur assignée et la 2e alerte vous montrera que l'affectation s'est produite.

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

4
Joel Coehoorn

Il est clair maintenant que ce ne sont pas les mêmes. Le moyen de coder c'est

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

Et, qu'en est-il de laisser assigment? Exactement la même chose que var, ne laissez pas l'assignation laisser vous confondre à cause de la portée du bloc.

let var1 = var2 = 1 // here var2 belong to the global scope

Nous pourrions faire ce qui suit:

let v1, v2, v3
v1 = v2 = v3 = 2

Remarque: au fait, je ne recommande pas d'utiliser plusieurs assignations, même pas plusieurs déclarations sur la même ligne.

0
fenderOne