【问题标题】:Why is Chrome making me declare my variable in this loop?为什么 Chrome 让我在这个循环中声明我的变量?
【发布时间】:2017-12-14 02:42:52
【问题描述】:

这种行为很奇怪。我有一个看起来像这样的对象数组:

myObjects = [
  { 
    name: 'List 1', 
    invitations: [
      { email: 'ralph@ralph.com', stamp: '1234' },
      { email: 'mike@mike.com', stamp: '4576' }
    ]
  },
  { 
    name: 'List 2', 
    invitations: [
      { email: 'steve@steve.com', stamp: '5678' },
      { email: 'bob@bob.com', stamp: '6789' }
    ]
  },
]

我需要过滤邀请数组包含某个电子邮件地址的对象,所以我正在这样做,当我在 Sublime Text 中测试它时效果很好:

filteredObjects = myObjects.filter(obj => { 
  for (invitation of obj.invitations) {
    if (invitation.email == 'bob@bob.com') return true;
  }
});

// [ { name: 'List 2', invitations: [ [Object], [Object] ] } ]

但是,如果我尝试在 Chrome 中运行它,它会让我出于某种原因在 for 循环中声明变量(注意 for 循环中添加的“var”):

filteredObjects = myObjects.filter(obj => { 
  for (var invitation of obj.invitations) {
    if (invitation.email == 'bob@bob.com') return true;
  }
});

如果我不声明变量(使用“var”),我的 Chrome 控制台中会出现错误:

Uncaught (in promise) ReferenceError: invitation is not defined

我想了解为什么会发生这种情况,以及是否有更好的方法来编写我的过滤器。

【问题讨论】:

  • 如果不声明invitation,它指的是什么?
  • 你在某处有使用严格吗?
  • 你是在问全局范围内是否还有另一个同名的变量?没有,我尝试了一些随机变量名称以确保它不是冲突问题。
  • @Alan:如果use strict 生效,变量必须在使用前用var(或let,或const)声明。 for (let invitation of obj.invitations) { 将为您提供最小范围的名称。
  • 不管是什么原因造成的,在使用变量之前,您应该始终使用letvar 声明变量。从错误消息中我猜你是通过一个缩小器/丑化器传递你的代码。

标签: javascript node.js google-chrome vue.js


【解决方案1】:

如果 Chrome 强制您声明变量 invitation,那是因为它阻止了隐式或意外的全局变量,那是因为您的代码位于 Chrome 认为 strict 模式的部分中。您必须向我们展示更大的代码上下文,以便我们准确辨别为什么它将代码视为strict 模式。

有一些浏览器的实现(例如 Firefox 中箭头函数的早期版本)在 strict 模式下自动生成箭头函数体,尽管这不是标准的一部分。或者,您的过滤器语句所在的这个更大的代码上下文可能由于某些其他原因而处于严格模式。

这是一件非常好的事情。所有变量都应在预期范围内明确声明。让您使用意外、隐式或自动全局变量编写代码是意外创建和使用冲突全局变量的秘诀。它会导致难以追踪甚至可能是间歇性行为的错误(尤其是涉及异步操作时)。

将自动执行严格模式:

  1. 手动将代码声明为strict 模式且'use strict'; 位于函数范围顶部的任何位置。

  2. 使用 ES6 Class 语法声明的方法会自动处于 strict 模式。

您可以在this article on MDNthis article on using Class 中查看严格模式效果的完整列表。

【讨论】:

  • 谢谢。在查看了上面的一些 cmets 之后,我确定这可能是 webpack 在捆绑期间发生的事情,因为如果您将代码直接复制并粘贴到 Chrome 控制台中,它可以在没有声明的情况下正常工作。但是,webpack 可能会在 Chrome 中触发严格模式,然后当它到达那个未声明的变量时,它给了我一个错误。学过的知识。总是声明。
  • @Alan - 听起来很可能。代码生成器喜欢在严格模式下运行他们的代码,因为它更精确地遵循严格的规则。您可以查看生成的代码,并可能确切地看到导致它的原因,或者只是将其作为结论。
猜你喜欢
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多