使用 JavaScript 进行多项左手赋值

IT技术 javascript variables variable-assignment
2021-01-16 05:00:17
var var1 = 1,
    var2 = 1,
    var3 = 1;

这相当于:

var var1 = var2 = var3 = 1;

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

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

有没有办法在 JavaScript 中确认这一点?可能使用一些分析器?

6个回答

实际上,

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

不是等同于:

var var1 = var2 = var3 = 1;

区别在于范围:

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示例等效于:

var var1 = (window.var2 = (window.var3 = 1));
我不明白……为什么 bad() 中的变量会在函数范围之外?当函数完成时,它们不应该被垃圾收集吗?
2021-03-16 05:00:17
确切地。但是如果我们遵循一些常见的最佳实践,在这种情况下,通过在顶部声明我们的变量,我们可以避免不必要的错误并避免局部变量泄漏到全局范围。参见:jsfiddle.net/gleezer/r9Mu8/1
2021-03-21 05:00:17
亲,出乎意料。谢谢你的提示,我会注意的。
2021-04-01 05:00:17
@SkinnyG33k 因为它从右到左。所以它会在最左边之前解析最右边。所以var var1=var2之后发生var3 = 1之后var2 = var3就像是var3=1; var2=var3; var var1=var2
2021-04-01 05:00:17
请注意:如果您知道要提前做这种事情,您仍然可以将定义与作业分开。所以:var v1, v2, v3;然后:v1 = v2 = v3 = 6;它们仍然在本地范围内。由于大卫提到了警报,这将按预期工作(如果预先设置):alert(v1 = v2 = v3 = 6);
2021-04-07 05:00:17

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

如果这些变量中的任何一个的值1在此语句之后,那么逻辑上它必须从右侧开始,否则值 orvar1var2将是未定义的。

你可以把它看作var var1 = (var2 = (var3 = 1));是最里面的一组括号首先被评估的地方。

这实际上是一个语法错误。你不能(马上拥有var删除外部括号允许它编译没有错误,var var1 = (var2 = (var3 = 1));. 当时我觉得它并没有很好地说明这一点,但我认为它是一样的。
2021-03-17 05:00:17
var var1 = var2 = var3 = 1;. 等于 var var3 = 1; var var2 = var3; var var1 = var2;
2021-03-23 05:00:17
谢谢,这绝对有帮助。如果不是从右到左求值(在这种情况下,错误是 var1/var2 未定义),那么考虑一下会抛出哪些错误会有所帮助。
2021-04-05 05:00:17

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

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

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

这不等同于:

var var1 = var2 = var3 = 1;

在这种情况下,screensvar关键字仅适用于var1由于变量提升而其余的表达式被正常评估,因此变量var2, var3正在成为全局变量

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

/*
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; 
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


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 既是函数又是结果值(相同的“事物”)。

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

windowInnerHeight(); // a thunk

试试这个:

var var1=42;
var var2;

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

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

从逻辑上讲,赋值必须从右到左链接。但是,由于这对 javascript 来说都是原子的(没有线程),因此特定引擎可能会选择以稍微不同的方式对其进行实际优化。

谢谢你的回答。我想我正在寻找一种使用警报的方法,同时仍然保持多分配结构 (a=b=c),但我认为这是不可能的。
2021-03-17 05:00:17
像 javascript 中的单个语句(尽管有几个表达式,但它们都适用于单个语句)可以被认为是原子的。你必须打破它。
2021-03-28 05:00:17