设置一个关键,如果没有设置 – 哪种方式是最有效的?

什么是最有效的方法来检查一个对象是否设置了一个键,如果没有,将其设置为一个给定的值? 请记住,这只适用于高性能的情况

让我们假设someCostlyOperation()需要大量的CPU时间来计算,永远不会返回一个falsy值

方法#1

 if(!myObj.myKey) myObj.myKey = someCostlyOperation(); 

方法#2

 myObj.myKey = myObj.myKey || someCostlyOperation(); 

概要:

  • 方法1检查myKey是否是虚假的。 如果undefined ,则将其设置为someCostlyOperation()

  • 方法#2没有条件,但总是重新分配myObj.myKey 。 如果是麻痹的话,它会将其设置为someCostlyOperation()

性能上的差异可能并不明显,但是在对这条线进行数万次评估的嵌套循环中,每一个小的优化都很重要,以便缩短执行时间并提高整体应用程序的性能。

我假设方法#1更快,因为它使方法#2所做的对myObj.myKey的检查相同,但是不会每次都无用地重新分配它。 我可能是错误的,因为我不知道所有的内部优化的JavaScript解释器使这样的代码(在我的情况下,它运行与Node.js)。

什么是完成这个最好的方法?


编辑

Arnauld在评论中提出了第三种方法。 这里是 :

方法#3

 !myObj.myKey && (myObj.myKey = someCostlyOperation()); 

这基本上是所有3种方法之间的联系。

 (function(){ var myObj = { }; var time1,time2,testTime1,testTime2,testTime3,test1Wins=0,test2Wins=0,test3Wins=0,noWinner=0; function someCostlyOperation(){ for(var i=0; i<100000; i++){ } return {}; } function method1(){ if(!myObj.myKey) myObj.myKey = someCostlyOperation(); } function method2(){ myObj.myKey = myObj.myKey || someCostlyOperation(); } function method3(){ !myObj.myKey && (myObj.myKey = someCostlyOperation()); } for(var i=0;i<10000;i++){ delete myObj.myKey; time1 = performance.now(); method3(); time2 = performance.now(); testTime1 = time2-time1; delete myObj.myKey; time1 = performance.now(); method2(); time2 = performance.now(); testTime2 = time2-time1; delete myObj.myKey; time1 = performance.now(); method3(); time2 = performance.now(); testTime3 = time2-time1; if(testTime1<testTime2 && testTime1<testTime3){ test1Wins++; } else if(testTime2<testTime3 && testTime2<testTime1){ test2Wins++; } else if(testTime3<testTime1 && testTime3<testTime2){ test3Wins++; } else{ noWinner++; } } console.log("test1Wins:",test1Wins); console.log("test2Wins:",test2Wins); console.log("test3Wins:",test3Wins); console.log("noWinners:",noWinner); })();