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条件,因为在整个循环运行过程中该条件是静态/恒定的

我能想到的几种方法是

  • 将循环保持在每个if/else块内。这样,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()
    函数只调用一次。然后,它根据条件只返回函数一次。该函数确实会为每个元素调用一次,但它只包含要为该条件运行的代码,而不是条件本身。我将再次更新答案,以明确这一点。