如果对象为空,则跳过 for 循环

Posted

技术标签:

【中文标题】如果对象为空,则跳过 for 循环【英文标题】:Skip over a for loop if object is empty 【发布时间】:2018-08-20 21:48:59 【问题描述】:

我主要来自 python 背景,所以我希望 for...in 循环一个空对象 跳过一起循环。然而事实并非如此。

我有一个循环可以简化为:

for (let y in x) 
    console.log(x[y]);
    if (x[y]['amount'] >= 0)
       x[y]['amount'] -= 1;
    

当使用x = 运行类方法时,它会记录undefined,表明循环已运行。

来自 python,我希望它像这段类似的代码一样跳过循环:

for y in x:
    print(y)
    if x[y]['amount'] >= 0:
        x[y]['amount'] -= 1

由于循环没有运行,它不打印任何内容。

有没有办法在 javascript 中实现类似的结果,如果对象为空,循环将不会运行?

谢谢。

【问题讨论】:

这应该可以按预期工作;您是通过将代码粘贴到开发人员控制台来运行它吗?如果是这样,您看到的只是代码的返回值。请参阅this SO question 了解更多信息 嗯,我不认为在 javascript 中,它有什么不同。 您可能会遇到这样的问题:对象上的for...in 循环将遍历它自己的键以及原型链上的键。你可以检查hasOwnProperty 或者你可以做一个for...of 循环而不是使用Object.keys(x):for (let key in Object.keys(x)) @phiter 我尽量保持简洁,但我想我会编辑它以包含完整的循环。 console.log(y, x[y]); 怎么样,这样你就可以看到它正在迭代哪些键 【参考方案1】:

对于空对象,不应运行该循环:https://repl.it/repls/SharpEducatedColdfusion。您可能只是从控制台看到输出undefined 为Hamms mentioned in the comments。或者有一个单独的、不相关的问题/console.log 为您提供该输出。


更新:我很好奇,所以我做了更多的挖掘。事实证明,tslint(Typescript 的 linting 工具)实际上需要检查才能使用 for...in 循环,因为这个确切的原因。 This answer 很好地解释了问题(这与这个问题中的问题相同)并为它提供了强有力的解决方案。

我会在这里总结一下。正如我之前提到的,问题的本质是基于for...in 循环如何查找原型链上的任何属性:

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

最适合您的用例的解决方案是:

for (let y in x) 
  if (x.hasOwnProperty(y)) 
    ...
  

这确保y 实际上是在对象x 上定义的,而不仅仅是在它的原型链上。对于遇到此问题并希望遍历对象上定义的所有字段的任何人,此解决方案适合您:

for (const field of Object.keys(x)) 
  ...


可能会引起此类混淆的相关内容是,您的 x 对象或其继承自的对象在其原型上具有 y 属性,但该属性未定义或在 x 上具有虚假值。您可以通过以下方式防止这种情况:

if (x.y) 
 ... your logic / loop here ...

请注意,上述检查将匹配 任何 falsy 值。

如果 x.yfalsenull 或其他虚假信息,您可以更明确地检查。

if (x.y !== undefined) 
 ... your logic / loop here ...

要了解更多关于编译器和let 声明关键字如何操作的信息,我非常喜欢Kyle Simpson 的书"You Don't Know JS - Scope and Closures"。

【讨论】:

x = y: false 上会发生什么?如果你想使用那个false怎么办? @binariedMe:答案是关于控制台的。这并不意味着问题是,或者它的代码是.. @binariedMe,我解释了为什么他会看到他在控制台中看到的内容,并为他提供了一种获得他正在寻找的功能的方法。我愿意接受有关如何改进我的答案的建设性反馈。对于 Scott 的问题,我已经更新了我的答案以说明您提到的情况。 @vincecampanale 实际上,问题不在于将 undefined 或 null 或 false 值作为对象的属性之一。如果对象本身是空的,那么他就弄错了控制台。正如其他 cmets 所暗示的,这可能是因为他可能在浏览器的控制台中运行它。但是无论如何,我们都不必通过您为空对象提供的解决方案。 是的,你是对的...repl.it/repls/SharpEducatedColdfusion -- 我会修正我的答案,但将内容保留在那里,因为它有点相关。但我现在同意我的回答是错误的。这是一个很好的收获,很抱歉吸收缓慢。

以上是关于如果对象为空,则跳过 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE查询条件为空,则跳过该条件。

如果数组为空则跳过foreach的最简洁方法[重复]

如果变量的值为空,则跳过变量的序列化? (自定义序列化)

如果函数内部的条件失败,则跳过 bash while 循环

VBA - 如何有条件地跳过for循环迭代

for循环