2017-09-18 52 views
-1

寻找最佳实践建议。函数调用可循环用于循环ES6

将中的函数调用作为可迭代对象是否是一种很好的做法?

const obj = {key1:'a', key2:'b'}; 

for(const i of Object.keys(obj)){ ... } 

或最好是有

const obj = {key1:'a', key2:'b'}; 
const allKeys = Object.keys(obj); 
for(const i of allKeys){ ... } 

不叫环路的每次迭代Object.keys功能?

+0

他们相当于 – damd

回答

4

您可以嘲讽一个类似的案件

function A(){ 
 
    console.log('function called'); 
 
    return [1, 2, 3, 4, 5]; 
 
} 
 

 
for(let i of A()){ 
 
    console.log(i); 
 
}

检查它,你可以看到一个()被调用一次

+0

*您可*,肯定的,但最好是有什么实际发生的理解。 –

+0

检查行为的好方法! – Roman

1

您的第一个示例与第二个示例的功能相同,只是没有allKeys常量。在你的第一个例子:

const obj = {key1:'a', key2:'b'}; 

for(const i of Object.keys(obj)){ ... 

... Object.keys只会被调用一次,然后它的迭代器将被检索并用于循环。 (这在规范中包含在ForIn/OfHeadEvaluation中,但它很重要)。所以你使用这种形式很好,但效率并不高。

0

Object.keys呼叫只在做一次两种变体。

还要考虑为这个可能性循环for不依赖于Object.keys

for (const prop in obj) { } 

Object.keys创建一个数组,而上述for循环不。后者只根据需要检索项目。当然,如果您的for循环永远不会提前退出,它仍然会检索所有这些循环,所以这只会在您计划提前退出循环时发挥作用。在这种情况下,相应的迭代器永远不会访问剩余的项目,而Object.keys已经在创建数组时完成了。

有一点要注意:一for .. in循环也将遍历枚举继承性能,不仅自己属性,同时Object.keys只列出自己枚举的属性。您可以在for循环添加一个额外的测试,以排除非自己的属性:

if (obj.hasOwnProperty(prop)) 
+0

当然应该是'in',而不是'''。感谢提及,@ T.J.Crowder。 – trincot

+0

啊......当然。出于某种原因,我没有对此作过分析。我建议调用re-inherited属性的区别。 –

+0

我很好奇你的断言,“上面的for'循环没有[创建数组],并且”只根据需要检索项目“。当然,它不会创建一个实际的数组,但我怀疑大多数或所有引擎都会准备一个所有密钥的内部列表 - 不是吗? –