在JavaScript中,链接分配好吗?

时间:2010-08-02 11:26:03

标签: javascript object variable-assignment

对JS或其语法不是新手,但有时候,语言的语义有时让我感到难过。在今天的工作中,一位同事提到了这一点:

var a = b = [];

不同
var a = [], b = [];

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

因为第一个版本实际上将对空数组的引用分配给a和b。我不能完全接受这一点,但我不确定。你们都在想什么?

6 个答案:

答案 0 :(得分:40)

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

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

不仅ab都被赋予了相同的值(对同一个空数组的引用),b根本没有被声明。在ECMAScript 5及更高版本的strict mode中,这将抛出ReferenceError;否则,除非范围中已存在变量b,否则b将作为全局对象的属性静默创建,并且与代码所在的全局变量类似,即使在函数内部也是如此。这不好。

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

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

window.console.log(b); // Shows []

答案 1 :(得分:9)

你的同事是对的:

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

但:

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

答案 2 :(得分:4)

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

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

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

答案 3 :(得分:3)

第一个示例b是对a的引用,b成为全局变量,可以从任何地方访问(并且它会替换可能已经存在的任何b变量存在于全球范围内)。

答案 4 :(得分:1)

要实现此目的,您需要从链接赋值中拆分var声明(请参阅: http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/)。

E.g。

var one = 1, two = 2;

one = two = 3; /* Now both equal 3 */

但如果你按照你所描述的那样(本例中为var one = two = 3;two泄漏到全局空间,而one在本地范围内声明。

答案 5 :(得分:0)

补充已提供的答案。 ref赋值与值赋值不同

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]

现在我们已经解决了2两个,你的问题也提到了linting,这是“漂亮的代码”(不是功能)的做法。事实上,JSHint has deprecated all their "pretty code rules"

话虽如此,我通常使用以下风格.-

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