简体   繁体   English

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

[英]Javascript ES6 Destructuring - Identifier 'location' has already been declared

I have a simple array of objects and want to get the location attribute of the first element: 我有一个简单的对象数组,想要获取第一个元素的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 

What am I missing? 我错过了什么?

You cannot redefine the global variable location as a constant. 您无法将全局变量location重新定义为常量。 Had you used let [{location}] = companies , you wouldn't have got an error, but you would have had the wrong behavior as it would try to assign a value to window.location and redirect the page. 如果你使用let [{location}] = companies ,你就不会有错误,但你会有错误的行为,因为它会尝试为window.location分配一个值并重定向页面。

Possible solutions: 可能的解决方案:

  • Change the variable name (along with the property name) 更改变量名称(以及属性名称)
  • Wrap your code in a block (IIFE is not necessary in this case since we are using ES6) 将代码包装在一个块中(在这种情况下不需要IIFE,因为我们使用的是ES6)
  • You can keep the property name and change the variable name, see the last example 您可以保留属性名称并更改变量名称,请参阅最后一个示例

 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); 

The problem here is that you're not wrapping your code inside a function. 这里的问题是你没有将代码包装在一个函数中。

If you use an IIFE (Immediately Invocated Function Expression) the same code will work. 如果您使用IIFE(立即调用函数表达式),相同的代码将起作用。

The reason your code fails is because you can't declare a constant in the same scope, if the constant/variable name is already taken. 代码失败的原因是因为如果已经采用了常量/变量名,则不能在同一范围内声明常量。

You could have used var instead of const but that would have assigned to window.location , effectively reloading the page and taking you to a 404 Page because that url doesn't exist. 您可以使用var而不是const但是已经分配给window.location ,有效地重新加载页面并将您带到404页面,因为该URL不存在。

That's why you should always write your code in an IIFE, to prevent global namespace pollution and nasty bugs that are hard to fix. 这就是为什么你应该总是在IIFE中编写你的代码,以防止全局命名空间污染和难以解决的令人讨厌的错误。

Here's the same code with an IIFE (added strict mode): 这是与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); })(); 

Or better yet: 或者更好的是:

 { // 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); }; 

The use of the ES2015 block won't pollute the global scope, given that you'll be using only let and const (and not using var ) 使用ES2015块不会污染全局范围,因为您将仅使用letconst (而不是使用var

Also, always remember that not all the browsers are supporting ES2015 syntax yet, so for now the code must be transpiled using Babel JS or similar tools. 另外,请记住并非所有浏览器都支持ES2015语法,所以现在必须使用Babel JS或类似工具来编译代码。

This happens because location has already been declared on global scope, as window.location . 发生这种情况是因为location已经在全局范围内声明,如window.location

To avoid this, this piece of code should not be executed in local scope, ie a block. 为了避免这种情况,这段代码不应该在本地范围内执行,即一个块。 This is ES6, while IIFEs are left-overs of ES5: 这是ES6,而IIFE则是ES5的遗留问题:

{
  ...
  const [{ location }] = companies; 
}

The typical use for ES6 is modular environment. ES6的典型用途是模块化环境。 Considering that current scope is CommonJS or ES6 module, the problem will never appear. 考虑到当前范围是CommonJS或ES6模块,问题将永远不会出现。

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

console.log(companies[0].location);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM