o2team/H5Skills

对象解构赋值无显式声明报错分析

Opened this issue · 1 comments

ES6 是要求变量需要声明后才能使用。不过,解构赋值是个例外:

{a, b} = {a: 1, b: 2}

相当于

let {a, b} = {a: 1, b: 2}

并不会报错。
这个似乎是一个漏洞,因为如果等号右边不是一个字面量,而是一个对象名,那么如果不加声明关键字就会报错如下:

let c = {a: 1, b: 2};
{a, b} = c; // Uncaught SyntaxError: Unexpected token =

其实只要显式加关键字就可以按预期地走:

let c = {a: 1, b: 2};
let {a, b} = c;

之所以会这样是 ES6 内部语法解析的问题:

  1. 当等号左右两边为字面量时,ES6 会认定左右都为模式,这个种情况下会进行解构赋值;
  2. 当等号右边为一个对象名与左边是一个对象字面量时,ES6 会把左右两边认定为对象,因为字面量不能赋值所以报错;
  3. 在字面量前加声明关键字,ES6 会认定关键字后的字面量是模式,整个表达式是一个解构赋值表达式。

不过,我发现这个漏洞只会发生成对象解构上。数组解构并不地出现。

[a, b] = [1, 2]; // 正常

正常

let c = [1, 2]; 
[a, b] = c; 

也正常

结论

尽管只有对象解构会发生意料之外的报错,但是为了良好习惯强烈建议解构赋值都显式加声明关键字:var/let。

赞👍