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

时间:2018-03-12 18:58:02

标签: javascript loops for-loop

我主要来自python背景,所以我希望module top(); localparam N=4; function automatic integer getk; input integer istop; input integer jstop; integer i,j,k; begin k=0; for (i=0; i<=istop; i=i+1) begin: firstfor for (j=i+1; j<((i==istop)? jstop : N); j=j+1) begin: secondfor k=k+1; end end getk=k; end endfunction genvar i,j; generate for (i = 0; i < N; i = i + 1) begin: firstfor for (j = i+1; j < N; j = j + 1) begin: secondfor localparam k = getk(i,j); initial $display("Created i=%0d j=%0d k=%0d",i,j,k); end end endgenerate endmodule 循环遍历空对象for...in以跳过所有在一起循环。但事实并非如此。

我有一个简化为此的循环:

{}

当使用for (let y in x) { console.log(x[y]); if (x[y]['amount'] >= 0){ x[y]['amount'] -= 1; } } 运行类方法时,它会记录x = {},表明循环已经运行。

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

undefined

因为循环没有运行所以它不打印任何东西。

无论如何在JavaScript中实现类似的结果,如果对象为空,循环将无法运行?

谢谢。

1 个答案:

答案 0 :(得分:4)

对于空对象,该循环不应运行:https://repl.it/repls/SharpEducatedColdfusion。您可能只是从控制台看到Hamms mentioned in the comments的输出undefined。或者有一个单独的,无关的问题/ 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属性但未定义或在{{1上有假值}}。您可以通过以下方式阻止:

x

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

如果if (x.y) { ... your logic / loop here ... } x.yfalse或其他错误,您可以更明确地查看。

null

要了解有关编译器和if (x.y !== undefined) { ... your logic / loop here ... } 声明关键字如何运作的更多信息,我真的很喜欢Kyle Simpson的书"You Don't Know JS - Scope and Closures"