在 JavaScript 中,链式赋值可以吗?
Posted
技术标签:
【中文标题】在 JavaScript 中,链式赋值可以吗?【英文标题】:In JavaScript, is chained assignment okay? 【发布时间】:2011-03-24 04:02:48 【问题描述】:我对 JS 或其语法并不陌生,但有时,该语言的语义有时让我感到困惑。今天上班,有同事提到这个:
var a = b = [];
不一样
var a = [], b = [];
或
var a = []; var b = [];
因为第一个版本实际上将对空数组的引用分配给 a 和 b。我不能完全接受这是真的,但我不确定。大家觉得呢?
【问题讨论】:
见***.com/questions/1758576/… 谢谢你,Crescent Fresh - 我没有完全看到这个问题,因为我正在寻找“链式作业”。 这能回答你的问题吗? Multiple left-hand assignment with javascript 【参考方案1】:是的,它们不一样。 var a = b = []
相当于
var a;
b = [];
a = b;
不仅a
和b
都被分配了相同的值(对同一个空数组的引用),b
根本没有被声明。在 ECMAScript 5 及更高版本的 strict mode 中,这将抛出 ReferenceError
;否则,除非在范围内已经存在变量b
,否则b
会作为全局对象的属性静默创建,并且无论代码在哪里,甚至在函数内部,其行为都类似于全局变量。哪个不好。
你可以很容易地看到这一点:
(function()
var a = b = [];
)();
console.log(b); // Shows []
【讨论】:
我没有立即看到 b 是一个全局变量,谢谢! +1 避免分配给不可解析引用的另一个原因是,在 ES5 上,在严格模式下,将抛出ReferenceError
。【参考方案2】:
你的同事是对的:
var a = b = [];
a.push('something');
console.log(b); // outputs ["something"]
但是:
var a = [],
b = [];
a.push('something');
console.log(b); // outputs []
【讨论】:
【参考方案3】:你的同事是对的。第一条语句创建一个新的空数组。然后,将此数组的引用分配给 b。然后,将相同的引用(这是赋值表达式的结果)分配给 a。所以 a 和 b 指的是同一个数组。
在所有其他情况下,您创建两个单独的数组。
顺便说一句:这种行为很常见,并且在所有基于 C 的编程语言中都是相同的。所以这不是 JavaScript 特有的。
【讨论】:
感谢您的回复,Tobias,也感谢您指出所有基于 C 语言的共性。 这个可以用JS中的数组来测试:["dog"] === ["dog"];
返回false,但是var a = b = ["dog"]; a === b;
返回true。【参考方案4】:
在第一个示例中,b
是对a
的引用,b
成为一个全局变量,可以从任何地方访问(它替换了可能已经存在于全局范围内的任何b
变量)。
【讨论】:
【参考方案5】:补充已经提供的答案。 ref 赋值不同于 value 赋值
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
【讨论】:
【参考方案6】:为此,您需要将 var
声明从链式赋值中分离出来(请参阅:
http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/)。
例如
var one = 1, two = 2;
one = two = 3; /* Now both equal 3 */
但是如果你按照你描述的那样做(在这个例子中是var one = two = 3;
)two
会泄漏到全局空间中,而one
是在本地范围内声明的。
【讨论】:
以上是关于在 JavaScript 中,链式赋值可以吗?的主要内容,如果未能解决你的问题,请参考以下文章