我对 JS 或其语法并不陌生,但有时,该语言的语义有时让我感到困惑。今天上班,同事提到了这个:
var a = b = [];
不一样
var a = [], b = [];
或者
var a = []; var b = [];
因为第一个版本实际上将空数组的引用分配给 a 和 b。我不能完全接受这是真的,但我不确定。大家怎么看?
我对 JS 或其语法并不陌生,但有时,该语言的语义有时让我感到困惑。今天上班,同事提到了这个:
var a = b = [];
不一样
var a = [], b = [];
或者
var a = []; var b = [];
因为第一个版本实际上将空数组的引用分配给 a 和 b。我不能完全接受这是真的,但我不确定。大家怎么看?
是的,它们不一样。var a = b = []
相当于
var a;
b = [];
a = b;
不仅双方a
并b
获得分配的值相同(相同的空数组的引用),b
是不是在所有的声明。在ECMAScript 5 及更高版本的严格模式下,这将抛出一个ReferenceError
; 否则,除非b
在作用域中已经有一个变量,否则它会b
被静默创建为全局对象的一个属性,并且其行为类似于全局变量,无论代码在哪里,甚至在函数内部。这不好。
你可以很容易地看到这一点:
(function() {
var a = b = [];
})();
console.log(b); // Shows []
你的同事是对的:
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 特定的。
第一个示例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