Javascript ES6 Destructuring - 标识符'location'已经被声明

Sta*_*erd 6 javascript ecmascript-6

我有一个简单的对象数组,想要获取第一个元素的location属性:

const companies = [
  { name: 'Google', location: 'Mountain View' },
  { name: 'Facebook', location: 'Menlo Park' },
  { name: 'Uber', location: 'San Francisco' }
];

const [{ location }] = companies; 
// expected: Mountain View but got Uncaught SyntaxError: Identifier 
//'location' has already been declared at <anonymous>:1:1
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Jua*_*des 11

您不能将全局变量重新定义location为常量.如果你使用过let [{location}] = companies,你就不会有错误,但你会遇到错误的行为,因为它会尝试为页面赋值window.location和重定向.

可能的解决方案:

  • 更改变量名称(以及属性名称)
  • 将代码包装在一个块中(在这种情况下不需要IIFE,因为我们使用的是ES6)
  • 您可以保留属性名称并更改变量名称,请参阅最后一个示例

const companies = [
  {name: 'Google',loc: 'Mountain View'},
  {name: 'Facebook', loc: 'Menlo Park'},
  {name: 'Uber', loc: 'San Francisco'}
];

const [{loc}] = companies;
console.log(loc);

// Block scope
{
  const companies = [
    {name: 'Google', location: 'Mountain View'},
    {name: 'Facebook', location: 'Menlo Park'},
    {name: 'Uber', location: 'San Francisco'}
  ];
  const [{location}] = companies;
  console.log(location);
}

// Variable name doesn't have to be the same as property
const [{ location: loca }] = [{location: 'Mountain View'}]
console.log(loca);
Run Code Online (Sandbox Code Playgroud)

  • `const [{location:loc}] = companies`也可以在任何范围内给你一个本地`const loc` (2认同)

Zor*_*one 5

这里的问题是您没有将代码包装在一个函数中。

如果您使用IIFE(立即调用函数表达式),则相同的代码将起作用。

代码失败的原因是,如果已经使用了常量/变量名称,则无法在相同范围内声明常量。

您可以使用var代替,const但可以将其分配给window.location,以有效地重新加载页面并将您带到404页面,因为该网址不存在。

这就是为什么您应该始终在IIFE中编写代码,以防止全局名称空间污染和难以修复的令人讨厌的错误的原因。

这是带有IIFE(添加严格模式)的相同代码:

(() => { // ES2015 IIFE
    "use strict";
    
    const companies = [
      { name: 'Google', location: 'Mountain View' },
      { name: 'Facebook', location: 'Menlo Park' },
      { name: 'Uber', location: 'San Francisco' }
    ];
    
    const [{ location }] = companies;
    console.log(location);
})();
Run Code Online (Sandbox Code Playgroud)

或者更好:

{ // ES2015 block
    "use strict";
    
    const companies = [
      { name: 'Google', location: 'Mountain View' },
      { name: 'Facebook', location: 'Menlo Park' },
      { name: 'Uber', location: 'San Francisco' }
    ];
    
    const [{ location }] = companies; 
    console.log(location);
};
Run Code Online (Sandbox Code Playgroud)

假设您仅使用letconst(而不使用var),则使用ES2015块不会污染全局范围

另外,请始终记住,并非所有浏览器都支持ES2015语法,因此,现在必须使用Babel JS或类似工具来转译代码。