在 JavaScript 中,链式赋值好吗?

IT技术 javascript object variable-assignment
2021-03-14 00:57:42

我对 JS 或其语法并不陌生,但有时,该语言的语义有时让我感到困惑。今天上班,同事提到了这个:

var a = b = [];

不一样

var a = [], b = [];

或者

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

因为第一个版本实际上将空数组的引用分配给 a 和 b。我不能完全接受这是真的,但我不确定。大家怎么看?

6个回答

是的,它们不一样。var a = b = []相当于

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

不仅双方ab获得分配的值相同(相同的空数组的引用),b是不是在所有的声明。ECMAScript 5 及更高版本的严格模式下,这将抛出一个ReferenceError; 否则,除非b在作用域中已经有一个变量,否则它会b被静默创建为全局对象的一个​​属性,并且其行为类似于全局变量,无论代码在哪里,甚至在函数内部。这不好。

你可以很容易地看到这一点:

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

console.log(b); // Shows []
我没有立即看到 b 是一个全局变量,谢谢!
2021-05-07 00:57:42
+1 避免对无法解析的引用赋值的另一个原因是,在 ES5 上,在严格模式下,ReferenceError将抛出 a。
2021-05-09 00:57:42

你的同事是对的:

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

但:

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

你的同事是对的。第一条语句创建一个新的空数组。然后,对该数组的引用分配给 b。然后,将相同的引用(这是赋值表达式的结果)分配给 a。所以 a 和 b 指的是同一个数组。

在所有其他情况下,您创建两个单独的数组。

顺便说一句:这种行为很常见,在所有基于 C 的编程语言中都是一样的。所以这不是 JavaScript 特定的。

这可以用 JS 中的数组来测试:["dog"] === ["dog"];返回 false,但var a = b = ["dog"]; a === b;返回 true。
2021-04-17 00:57:42
感谢 Tobias 的回复,也感谢您指出所有基于 C 的语言的共性。
2021-05-11 00:57:42

第一个示例b是对 的引用a,并b成为可从任何地方访问的全局变量(并替换b可能已存在于全局作用域中的任何变量)。

补充已经提供的答案。引用赋值不同于值赋值

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]

既然我们已经解决了 22,您的问题也提到了 linting,这是“漂亮代码”(非功能性)的做法。事实上,JSHint 已经弃用了他们所有的“漂亮代码规则”

话虽如此,我通常使用以下样式。-

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