ChatGPT解决这个技术问题 Extra ChatGPT

tslint / codelyzer / ng lint 错误:“for (... in ...) 语句必须使用 if 语句过滤”

皮棉错误消息:

src/app/detail/edit/edit.component.ts[111, 5]: for (... in ...) 语句必须用 if 语句过滤

代码片段(它是一个工作代码。它也可以在 angular.io form validation section 获得):

for (const field in this.formErrors) {
      // clear previous error message (if any)
      this.formErrors[field] = '';
      const control = form.get(field);

      if (control && control.dirty && !control.valid) {
        const messages = this.validationMessages[field];
        for (const key in control.errors) {
          this.formErrors[field] += messages[key] + ' ';
        }
      }
    }

知道如何解决这个 lint 错误吗?

也许接受答案?

a
akrabi

为了解释 tslint 指出的实际问题,引用 for...in statement 的 JavaScript 文档:

循环将遍历对象本身的所有可枚举属性以及对象从其构造函数的原型继承的那些属性(原型链中更接近对象的属性会覆盖原型的属性)。

因此,基本上这意味着您将获得您可能不希望获得的属性(来自对象的原型链)。

为了解决这个问题,我们只需要迭代对象自己的属性。我们可以通过两种不同的方式来做到这一点(正如@Maxxx 和@Qwertiy 所建议的那样)。

第一个解决方案

for (const field of Object.keys(this.formErrors)) {
    ...
}

这里我们使用 Object.Keys() 方法返回给定对象自己的可枚举属性的数组,其顺序与 for...in 循环提供的顺序相同(不同之处在于 for-in 循环枚举原型中的属性链也一样)。

第二种解决方案

for (var field in this.formErrors) {
    if (this.formErrors.hasOwnProperty(field)) {
        ...
    }
}

在此解决方案中,我们迭代对象的所有属性,包括其原型链中的属性,但使用 Object.prototype.hasOwnProperty() 方法,该方法返回一个布尔值,指示对象是否具有指定的属性作为自己的(非继承的)属性,以过滤掉继承的属性.


我想注意 Object.keys 是 ES5。来自 ES6 的唯一东西是 for-of 循环。我们可以在通常的循环中从 0 到它的长度迭代数组,它将是 ES5。
再次注意:如果 this.formErrors 以某种方式为空,则 for...in 什么也不做,而 for ... of Object.keys() 会抛出错误。
我正在遵循第二个解决方案,但我仍然看到 lint 消息。暂时禁用 lint。
为什么不推荐 Object.keys(obj).forEach( key => {...})
@BenCarp - 在异步函数中运行时存在严重问题,因此,至少对我来说, for ... in/of ... 被认为更优越。请参阅:stackoverflow.com/questions/37576685/…
M
Maxxx

应用@Helzgate 回复的一种更简洁的方法可能是将您的“for .. in”替换为

for (const field of Object.keys(this.formErrors)) {

这应该是公认的答案,因为它不仅解决了问题,而且与 if (this.formErrors.hasOwnProperty(field)) 等附加条件相比,它还减少了样板代码的数量。
请注意答案,它可能会破坏您的代码。在“修复”它之后进行测试。
这实际上并没有为我消除 tslint 错误。
@HammerN'Songs 检查您是否更改为 for of 而不是 for in
同样的问题。使用此错误后未删除
Q
Qwertiy
for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {

P
Post Impatica

使用 Object.keys:

Object.keys(this.formErrors).map(key => {
  this.formErrors[key] = '';
  const control = form.get(key);

  if(control && control.dirty && !control.valid) {
    const messages = this.validationMessages[key];
    Object.keys(control.errors).map(key2 => {
      this.formErrors[key] += messages[key2] + ' ';
    });
  }
});

N
Nick

如果 for(... in ...) 的行为对于您的目的是可接受/必要的,您可以告诉 tslint 允许它。

在 tslint.json 中,将其添加到“规则”部分。

"forin": false

否则,@Maxxx 有正确的想法

for (const field of Object.keys(this.formErrors)) {

编辑 tslint.json....快速、简单且效果很好。优秀的答案!
l
lukas_o

我认为此消息不是要避免使用 switch。相反,它希望您检查 hasOwnProperty。背景可以在这里阅读:https://stackoverflow.com/a/16735184/1374488