es6阵列解构怪异

ron*_*kot 8 javascript ecmascript-6

谁能解释一下,为什么ES6阵列解构会发生以下情况?

let a, b, c
[a, b] = ['A', 'B']
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)

// expected: a=A b=BB c=C
// actual:   a=BB b=C c=undefined
Run Code Online (Sandbox Code Playgroud)

http://codepen.io/ronkot/pen/WxRqXg?editors=0011

Ber*_*rgi 12

正如其他人所说,你丢失了分号.但…

谁能解释一下?

在您的行之间没有自动插入分号来分隔"两个"语句,因为它作为单个语句有效.它被解析(并评估)为

let a = undefined, b = undefind, c = undefined;
[a, b] = (['A', 'B']
[(b, c)] = ['BB', 'C']);
console.log(`a=${a} b=${b} c=${c}`);
Run Code Online (Sandbox Code Playgroud)

其中,

  • [a, b] = …; 是预期的解构任务
  • (… = ['BB', 'C']) 是一个赋值表达式,将数组分配给左侧,并对数组求值
  • ['A', 'B'][…]是数组文字的属性引用
  • (b, c)正在使用逗号运算符,评估为c(即undefined)


Ole*_*leg 6

您已经陷入了 JavaScript 中换行和自动分号插入规则的陷阱。

拿这个例子:

let x = [1, 2]
[2, 1]
Run Code Online (Sandbox Code Playgroud)

它的解释为:

let x = [1, 2][2, 1] // === [1, 2][(2, 1)] === [1, 2][1] === 2
Run Code Online (Sandbox Code Playgroud)

[(2, 1)]上面那个奇怪的东西与逗号运算符的工作方式有关。

因此,您的示例:

let a, b, c
[a, b] = ['A', 'B']
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Run Code Online (Sandbox Code Playgroud)

解释为:

let a, b, c
[a, b] = ['A', 'B'][b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Run Code Online (Sandbox Code Playgroud)

现在,如果您插入分号,它将按您的预期工作:

let a, b, c
[a, b] = ['A', 'B']; // note a semicolon here
[b, c] = ['BB', 'C']
console.log(`a=${a} b=${b} c=${c}`)
Run Code Online (Sandbox Code Playgroud)

此外,通过将代码粘贴到Babel repl 中以查看生成的输出来检查代码也是一个好主意:

'use strict';

var a = void 0,
    b = void 0,
    c = void 0;

var _ref = ['A', 'B'][(b, c)] = ['BB', 'C'];

a = _ref[0];
b = _ref[1];

console.log('a=' + a + ' b=' + b + ' c=' + c);
Run Code Online (Sandbox Code Playgroud)