关于变量:使用JavaScript进行多次左手赋值

Multiple left-hand assignment with JavaScript

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

这相当于:

1
var var1 = var2 = var3 = 1;

我很确定这是变量定义的顺序:var3,var2,var1,这相当于:

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

在javascript中有没有什么方法可以确认这一点?可能使用一些分析器?


事实上,

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

不等于:

1
var var1 = var2 = var3 = 1;

区别在于范围:

1
2
3
4
5
6
7
8
9
10
11
12
13
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!

实际上,这表明赋值是右相关的。bad示例等效于:

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


javascript中的赋值从右到左工作。var var1 = var2 = var3 = 1;

如果这些变量中的任何一个的值在该语句之后是1,那么逻辑上它必须从右边开始,否则该值或var1var2将不被定义。

您可以将其视为等同于var var1 = (var2 = (var3 = 1));,其中最内部的一组括号是首先计算的。


1
2
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)在逻辑上是(a ? b : a),表现为乘法(如!!a * !!b)

(a || b)在逻辑上是(a ? a : b),表现为加法(如!!a + !!b)

(a = 0, b)是不关心a是否真实的简称,含蓄地返回b

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

javascript运算符优先级(操作顺序)

请注意,逗号运算符实际上是特权最小的运算符,但括号是特权最大的运算符,在构造一行表达式时,它们会同时使用。

最后,您可能需要"thunk"而不是硬编码值,对我来说,thunk既是函数又是结果值(相同的"thing")。

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

windowInnerHeight(); // a thunk

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

在这种情况下,var关键字适用于所有三个变量。

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

不等于:

var var1 = var2 = var3 = 1;

在这种情况下,由于变量提升,屏幕后面的var关键字只适用于var1,表达式的其余部分被正常计算,因此变量var2, var3正在成为全局变量。

javascript按以下顺序处理此代码:

1
2
3
4
5
6
7
8
/*
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;


试试这个:

1
2
3
4
5
var var1=42;
var var2;

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

注意第一个警报中的单个"="。这将显示分配表达式的结果是分配的值,第二个警报将显示分配确实发生了。

从逻辑上讲,分配必须从右到左链接。但是,由于这对JavaScript来说都是原子的(没有线程),因此特定的引擎可能会选择实际优化它,但有点不同。


现在很明显,它们是不一样的。编码的方法是

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

那么,让我们分配呢?与var完全相同,不要因为块范围而让let分配混淆您。

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

我们可以这样做:

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

注意:顺便说一句,我不建议在同一行中使用多个赋值,甚至不建议使用多个声明。


coffee-script能平稳地完成这一任务。

1
for x in [ 'a', 'b', 'c' ] then"#{x}" : true

[ { a: true }, { b: true }, { c: true } ]