数组文字的链式赋值与重复文字表达式的多个单独赋值相同吗?

问题描述 投票:0回答:7

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

var a = b = [];

不一样
var a = [], b = [];

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

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

javascript object variable-assignment
7个回答
60
投票

是的,它们不一样。

var a = b = []
相当于

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

不仅

a
b
都被分配了相同的值(对同一空数组的引用),而且
b
根本没有声明。在 ECMAScript 5 及更高版本的严格模式中,这将抛出一个
ReferenceError
;否则,除非作用域中已经存在变量
b
,否则
b
会默默地创建为全局对象的属性,并且无论代码位于何处,甚至在函数内部,其行为都与全局变量类似。这不好。

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

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

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

13
投票

你的同事是对的:

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 特有的。


3
投票

在第一个示例中,

b
是对
a
的引用,并且
b
成为全局变量,可以从任何地方访问(并且它替换可能已存在于全局范围中的任何
b
变量)。


3
投票

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

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]

现在我们已经解决了两个问题,您的问题还提到了 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

1
投票

要实现此目的,您需要将

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
则在本地范围中声明。


1
投票

既然你的问题是是否可以,那么除了严格模式之外,都可以。模块默认处于严格模式,因此不允许。

<script>
  const a=b=1 // allowed
<script>
<script>
  "user strict"
  const a=b=1 // error
<script>
<script type="module">
  const a=b=1 // error
<script>
© www.soinside.com 2019 - 2024. All rights reserved.