Javascript 有没有办法使if的条件保持静态/恒定?
假设我有这样一个片段Javascript 有没有办法使if的条件保持静态/恒定?,javascript,performance,if-statement,optimization,branch-prediction,Javascript,Performance,If Statement,Optimization,Branch Prediction,假设我有这样一个片段 let arr = [{...},{...} ...]// huge array of objects; arr.forEach(i => { if(someOtherProperty == "one") { ... } else if(someOtherProperty == "two") { ... }... }) 基本上,我在一个循环中有一个if-else-if梯形图 该条件不依赖于数组项 我想知道是否有可能在执行循环之前评估i
let arr = [{...},{...} ...]// huge array of objects;
arr.forEach(i => {
if(someOtherProperty == "one") {
...
} else if(someOtherProperty == "two") {
...
}...
})
基本上,我在一个循环中有一个if-else-if梯形图
该条件不依赖于数组项
我想知道是否有可能在执行循环之前评估if条件,因为在整个循环运行过程中该条件是静态/恒定的
我能想到的几种方法是
let condition = {
one: someOtherProperty == "one",
two: someOtherProperty == "two",
...
}
并在类似于if(condition.one)等条件下使用它
请提出更好的方法来处理这种情况,以提高效率我认为在这种情况下,条件内部的代码之间存在巨大差异,可以使用以下方法使代码看起来更好:
让arr=[1,2,3,4,5];
让str=“一”;
常数条件={
“一”:功能(项目、索引){
控制台日志(“一”,项目);
},
“二”:功能(项目、索引){
控制台日志(“两个”,项目);
}
}
arr.forEach(条件[str])代码>要保存代码重复,可以执行一次条件检查,迭代循环,然后将其余代码放入函数中
您还可以将循环迭代代码放在函数中并调用该函数,具体取决于您在循环中执行的操作
let arr = [{...},{...} ...]// huge array of objects;
if(someOtherProperty == "one") {
arr.forEach(i => { ...functionOnArray(); });
functionOne();
} else if(someOtherProperty == "two") {
arr.forEach(i => { ...functionOnArray(); });
functionTwo();
}...
function functionOnArray(){ ... }
function functionOne(){ ... }
function functionTwo(){ ... }
可以做的一件事是创建一个映射到数组的分支非匿名函数。例如
f = {(x => if (prop1 == "one")
{ ...}
else if (prop2 == "two")
{...} )}
然后执行arr.forEach(i=>f(i))
。这正是javascript的功能特性实现的目的
这大致上和您试图做的一样有效。如果您尝试巧妙地处理这些条件并将其作为参数传递给该函数,它将变得更快 想到的最佳解决方案是使用函数方法
let arr = [1,2,3,4,5,6,7,8,9]; // Huge array
let condFactory = (condition) => {
if (condition === 'one') {
console.log('This will only be called once, if condition==="one"',
'it will not be called for each element')
return (item, index) => console.log('one (called for each element)', item, index);
} else if (condition === 'two') {
console.log('This will only be called once, if condition==="two"',
'it will not be called for each element')
return (item, index) => console.log('two (called for each element)', item, index);
}
console.log('This will only be called once, if no condition matches',
'it will not be called for each element')
return (item, index) => console.log('No condition matched (called for each element)', item, index);
}
arr.forEach(condFactory(someOtherProperty));
对于es5:
var arr = [1,2,3,4,5,6,7,8,9]; // Huge array
var condFactory = function(condition) {
if (condition === 'one') {
console.log('This will only be called once, if condition==="one"',
'it will not be called for each element')
return function(item, index) { console.log('one (called for each element)', item, index); };
} else if (condition === 'two') {
console.log('This will only be called once, if condition==="two"',
'it will not be called for each element')
return function(item, index) { console.log('two (called for each element)', item, index); };
}
console.log('This will only be called once, if no condition matches',
'it will not be called for each element')
return function(item, index) { console.log('No condition matched', item, index); };
}
arr.forEach(condFactory(someOtherProperty));
这样,将在循环开始之前确定用于每个条件的函数,并用于循环中的每个元素
let arr = [{...},{...} ...]// huge array of objects;
if(someOtherProperty == "one") {
arr.forEach(i => { ...functionOnArray(); });
functionOne();
} else if(someOtherProperty == "two") {
arr.forEach(i => { ...functionOnArray(); });
functionTwo();
}...
function functionOnArray(){ ... }
function functionOne(){ ... }
function functionTwo(){ ... }
你可以拉伸这一行
arr.forEach(condFactory(someOtherProperty));
分成两行,以了解为什么if…else只计算一次:
let functionBasedOnIfElse = condFactory(someOtherProperty); // Get the function based on your "someOtherProperty"
arr.forEach(functionBaseOnIfElse); // Pass reference to the function
如您所见,if…else将只计算一次。然后,if…else上返回的函数将传递给arr.forEach并为数组中的每个元素调用
编辑:添加默认返回
编辑2:已更正es5被剪断
Edit3:展开事例以显示每个函数都应用于数组中的每个项
Edit4:添加更多关于为什么if…else只计算一次的信息
Edit5:添加一些console.log
来显示在哪一点调用哪个部分。你能解释一下你想要实现什么吗?@Phiter,感觉代码效率很低。因为数组的大小很大,而且还有很多其他的if块。对于每个迭代,我认为可以在循环运行之前对条件进行评估,但不知道最好的方法。在这里使用switch
语句行吗?我不太确定我是否理解这个问题。@jhpratt看到我的上述评论,我想我已经说得更清楚了。如果预期结果一致,则可能会或可能不会影响if
语句的速度,因此可能根本不需要进行预优化。由于上下文切换开销,最大的问题是使用forEach()
而不是for
语句。该语法甚至无效。它与问题中的代码段等效。x=>if(…)
与x=>{if(…)}
不等效。前者是一个语法错误。无括号箭头函数中不能存在非表达式语句。您的代码段/方法与所提供的代码段/方法有何不同?condFactory(someOtherProperty)
根据条件返回函数。展开示例:let determinedFunction=condFactory(someOtherProperty);//基于条件的函数
arr.forEach(determinedFunction)//通过这种方式传递函数引用
,if…else将只确定一次->基于返回的函数->将为数组中的每个元素调用此函数。我将更新答案以包含此内容。@SatishKumar我更新了我的答案,以说明它与问题中的方法有何不同。我相信您关于“以这种方式,如果……否则将只确定一次”部分的看法是错误的。您刚刚传递了该函数,将为数组中的每个元素调用它。因此,每次都将对条件进行评估。还有问题中的片段和你的等效片段。你所做的只是把循环体放在一个函数中,这不是真的。condFactory()
函数只调用一次。然后,它根据条件只返回函数一次。该函数确实会为每个元素调用一次,但它只包含要为该条件运行的代码,而不是条件本身。我将再次更新答案,以明确这一点。