在 JavaScript 中,链式赋值好吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3387247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In JavaScript, is chained assignment okay?
提问by JamieJag
Am not new to JS or its syntax, but sometimes, the semantics of the language has me stumped at times. At work today, a colleague mentioned this:
我对 JS 或其语法并不陌生,但有时,该语言的语义有时让我感到困惑。今天上班,同事提到了这个:
var a = b = [];
is not the same as
不一样
var a = [], b = [];
or
或者
var a = []; var b = [];
since the first version actually assigns the reference to an empty array to a and b. I couldn't quite accept this as true, but I'm not sure. What do you all think?
因为第一个版本实际上将空数组的引用分配给 a 和 b。我不能完全接受这是真的,但我不确定。大家怎么看?
回答by Tim Down
Yes, they're not the same. var a = b = []is equivalent to
是的,它们不一样。var a = b = []相当于
var a;
b = [];
a = b;
Not only do both aand bget assigned the same value (a reference to the same empty array), bis not declared at all. In strict modein ECMAScript 5 and later, this will throw a ReferenceError; otherwise, unless there is already a variable bin scope, bis silently created as a property of the global object and acts similarly to a global variable, wherever the code is, even inside a function. Which is not good.
不仅双方a并b获得分配的值相同(相同的空数组的引用),b是不是在所有的声明。在ECMAScript 5 及更高版本的严格模式下,这将抛出一个ReferenceError; 否则,除非b在作用域中已经有一个变量,否则它会b被静默创建为全局对象的一个属性,并且其行为类似于全局变量,无论代码在哪里,甚至在函数内部。这不好。
You can see this quite easily:
你可以很容易地看到这一点:
(function() {
var a = b = [];
})();
console.log(b); // Shows []
回答by Daniel Vassallo
Your colleague is right:
你的同事是对的:
var a = b = [];
a.push('something');
console.log(b); // outputs ["something"]
but:
但:
var a = [], b = [];
a.push('something');
console.log(b); // outputs []
回答by h2stein
Your colleague is right. The first statement creates a new, empty array. Then, a reference to this array is assigned to b. Then, the same reference (which is the result of the assignment expression) is assigned to a. So a and b refer to the same array.
你的同事是对的。第一条语句创建一个新的空数组。然后,对该数组的引用分配给 b。然后,将相同的引用(这是赋值表达式的结果)分配给 a。所以 a 和 b 指的是同一个数组。
In all other cases, you create two individual arrays.
在所有其他情况下,您创建两个单独的数组。
By the way: This behavior is quite common and is the same in all C based programming languages. So this is not JavaScript specific.
顺便说一句:这种行为很常见,在所有基于 C 的编程语言中都是一样的。所以这不是 JavaScript 特定的。
回答by Fabien Ménager
With the first example bis a reference to a, and bbecomes a global variable, accessible from anywhere (and it replaces any bvariable that may already exist in the global scope).
第一个示例b是对 的引用a,并b成为可从任何地方访问的全局变量(并替换b可能已存在于全局作用域中的任何变量)。
回答by Campbeln
To accomplish this, you need to split the vardeclaration from the chained assignment (see:
http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/).
为此,您需要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 */
But if you do as you described (var one = two = 3;in this example) twoleaks into the global space, while oneis declared in the local scope.
但是如果你按照你的描述去做(var one = two = 3;在这个例子中)会two泄漏到全局空间,而one在局部范围内声明。
回答by percebus
To complement the already provided answers. ref assignments are different from value assignments
补充已经提供的答案。引用赋值不同于值赋值
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]
Now that we've addressed 2 two, your question also makes reference to linting, which is the practice of "pretty code" (not functional). In fact, JSHint has deprecated all their "pretty code rules"
既然我们已经解决了 22,您的问题也提到了 linting,这是“漂亮代码”(非功能性)的做法。事实上,JSHint 已经弃用了他们所有的“漂亮代码规则”
That been said, I usually use the following style.-
话虽如此,我通常使用以下样式。-
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

