简体   繁体   English

是否可以动态重写您的JavaScript

[英]Is it possible to rewrite your javascript dynamically

I would like to edit my if else statement in javascript dynamically. 我想在javascript中动态编辑if else语句。

So after one if statement is used, it could be removed. 因此,在使用了一个if语句之后,可以将其删除。 I get this maybe isn't possible but after a search online failed, my curiosity begged me to ask. 我知道这也许是不可能的,但是在网上搜索失败后,我好奇地求我问。

For instance: 例如:

if (x > 200 && x % 25 === 0) {
  doSomething1();
} else if (x > 300 && !inRange) {
  doSomething2();
} else if (x > 400 && x % 7 === 0) {
  doSomething3();
}

There are eight if else statements within this loop. 此循环中有八个if else语句。 The loop determines which object to create. 循环确定要创建的对象。 There are 2000 objects created over the course of a couple minutes. 在几分钟内创建了2000个对象。 If on average we reach the fourth statement before it breaks, then there are 8,000 calculations being performed just within this one set of statements. 如果平均而言,我们在中断前达到第四个语句,则仅在这一组语句中执行了8,000个计算。

I want to streamline the script for speed and again, curiosity if we can actually write javascript dynamically without using separate functions etc. After an if statement fails, it is often not required anymore. 我想简化脚本,以便提高速度,并且提高好奇心,如果我们实际上可以动态地编写JavaScript而无需使用单独的函数等。if语句失败后,通常不再需要它。 The next statement could I suppose, include code to remove its predecessor dynamically. 我想下一个语句可以包括动态删除其前身的代码。 This might save 3 or 4 thousand calculations - not huge I know, but worthy of consideration given that there are lots of other things going on as well. 这可能会节省3或4千次计算-我知道不是很大,但是考虑到还有很多其他事情在进行,因此值得考虑。

Is there a way to remove them dynamically or does anyone have any tricks or patterns up their sleeves? 有没有一种方法可以动态删除它们,或者有人没有袖手旁观的花样或图案?

Also, even if this is not available in js, what would this be called? 另外,即使这在js中不可用,这又叫什么呢?

Why would you want to remove them dynamically? 您为什么要动态删除它们? Altering the code dynamically is unnecessary and a bag of worms that's overdoing it for this situation. 动态更改代码是不必要的,在这种情况下,一堆蠕虫会过度使用它。 You should be using a flag. 您应该使用一个标志。

I'll answer separately for whether you're trying to skip a large group of if statements, or an individual if statement. 对于您是要跳过一大堆if语句还是要跳过单个if语句,我将分别回答。

Foreword 前言

As mentioned in the comments on your question, run profiling to make sure you know where your performance problems are! 如对问题的评论中所述,请运行性能分析以确保您知道性能问题在哪里!

You mention your aversion to simply using boolean flags to make an if statement not run in your answer. 您提到您不喜欢仅使用布尔标志使if语句不在您的答案中运行。 This is fine, and it's what people normally do. 很好,这是人们通常所做的。 This should not be an actual performance concern, and profiling will probably show your performance problems lie elsewhere. 这不应该是实际的性能问题,分析可能表明您的性能问题出在其他地方。 If they don't and this boolean flag check is genuinely your bottleneck - you have bigger problems, such as expecting too much from your JavaScript code, or that you didn't use the profiling tool correctly, or misinterpreted its results. 如果不这样做,并且布尔标志检查确实是您的瓶颈,那么您将遇到更大的问题,例如对JavaScript代码的期望过高,或者您没有正确使用分析工具,或者错误地解释了其结果。

If you're trying to avoid running the body of an if statement, or its conditions, those are a bigger performance concern to you than the boolean flag check itself. 如果您试图避免运行if语句的主体或其条件,那么与boolean标志检查本身相比,这些问题对您来说是更大的性能问题。

For skipping a large group of if statements 用于跳过大量的i​​f语句

Wrap your bunch of if statements in a condition. 在条件中包装一堆if语句。

if (runBunchOfIfStatements) {
    // all those if statements here
}

When you're past the point of wanting those if statements to run, set the runBunchOfIfStatements flag to false (of course, you should probably pick a more meaningful name than that). 当您不希望运行这些if语句时,请将runBunchOfIfStatements标志设置为false(当然,您可能应该选择比它更有意义的名称)。

That said, 8 or 9 if statements is a code length issue, and more than likely means nothing at all for performance concerns - unless those if statements happen to involve very intensive checks. 就是说,8或9 if语句是一个代码长度问题,并且很可能根本不涉及性能问题-除非这些if语句碰巧涉及非常密集的检查。 If you're worried just because there's a lot of if checks, you're probably looking in the wrong place. 如果您只是因为有很多if检查而感到担心,那么您可能在寻找错误的地方。

For individual if statements 对于个人if语句

Say you have only one if statement you want to skip. 假设您只有一个 if语句要跳过。 You had this code in your answer: 您的答案中包含以下代码:

} else if (x > 300 && !doneSomething2) {
  doSomething2();
  doneSomething2 = 1;
}

This is fine. 这可以。 You're just making a tiny check: see the foreword. 您只是在做些小检查:请参见前言。 Look elsewhere for your performance concern. 寻找其他地方关注您的性能。 It could be rewritten slightly to more closely follow convention (which I'm about to get to), but in this situation, the change will have negligible impact. 可以稍作重写以更严格地遵循约定(我将要达成),但是在这种情况下,更改的影响可忽略不计。

Let's take a situation where there is actually a performance concern here. 让我们的情况下居然还有一个性能问题在这里。 Suppose that instead of checking x > 300 you're doing something more intensive like calculateSeveralSquareRoots() . 假设您没有进行x > 300的检查,而是进行了更密集的工作,例如calculateSeveralSquareRoots() Generally, you do take this approach, but you rearrange it like this: 通常,您确实会采用这种方法,但是您会像这样重新排列它:

} else if (needCalculations && calculateSeveralSquareRoots() {
    // do stuff
    needCalculations = false;
}

The difference here is the needCalculations flag comes first , not second. 此处的区别是needCalculations标志排在第一位 ,而不是第二位。 JavaScript's comparison operators have short circuit evaluation . JavaScript的比较运算符具有短路评估 This means that when evaluating a && b , if a is false, b never even gets checked - we already know the result will be false. 这意味着在评估a && b ,如果a为假,则b甚至不会被检查-我们已经知道结果将为假。 If the flag comes first, that means calculateSeveralSquareRoots() never gets run, and you save time on the check. 如果该标志排在最前面,则意味着永远不会运行calculateSeveralSquareRoots() ,从而节省了检查时间。

If the flag came second, then you're potentially wasting a lot of time on that function for a condition that might almost always resolve to false anyway thanks to that flag. 如果该标志排在第二位,那么您可能会在该函数上浪费大量时间,因为这种情况几乎总是会由于该标志而解析为false。

So in your original, you could have the flag come before the x > 300 evaluation, just to follow convention. 因此,在你原来的,你可能有之前的标志来x > 300的评价,只是遵循惯例。 But again... if an if statement like this is a real and significant performance concern for you, then you have bigger issues. 但是再说一次…… 如果像这样的if语句对您来说是真正的重要性能问题,那么您将遇到更大的问题。

No. And the need for such would indicate poor design. 否。需要这样做将表明设计不佳。

You should use a conditional expression to determine when which code segment should be run, as you mention. 正如您提到的,您应该使用条件表达式来确定应在何时运行哪个代码段。 If you pass a certain threshold within your code after which you no longer want a condition to be executed in your loop, why not simply break the loop and have a new code block handling the doSomethingElse clause. 如果您在代码中传递了一定的阈值,然后不再希望在循环中执行条件,为什么不简单地break循环并拥有一个新的代码块来处理doSomethingElse子句。 If you're using setInterval , that's the point at which you would call clearInterval , and then trigger some new action if necessary. 如果使用setInterval ,那就是调用clearInterval ,然后在必要时触发一些新操作。 Anyway, running a single (or even a few) simple conditional statement doesn't add much overhead, and isn't likely to be the limiting factor in your optimization anyway. 无论如何,运行单个(甚至几个)简单的条件语句不会增加太多开销,而且无论如何也不会成为优化的限制因素。

Ignoring the fact that I doubt this is a bottleneck in modern browsers that JIT the JavaScript (CPUs are very good at predictive branching) as shown because simple number comparison is not going to be expensive even in large iterations with smart predictions once it's compiled. 我忽略了这样一个事实,即我怀疑这是现代浏览器的瓶颈,因为它如图所示将JIT JavaScript(CPU非常擅长预测分支),因为即使编译后使用智能预测进行大迭代,简单的数字比较也不会很昂贵。

You can do this by injecting a different function: 您可以通过注入其他功能来做到这一点:

checker: function(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (x > 300) {
        doSomething2();
    }
    else if (y > 400) {
        doSomething3();
    }
}

Can be changed to 可以更改为

checker: function(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (x > 300) {
        doSomething2();
        this.checker = smallerChecker;
    }
    else if (y > 400) {
        doSomething3();
    }
}

function smallerChecker(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (y > 400) {
        doSomething3();
    }
}

Fundamentally, you simply need to make the behavior injectable, and then you change it however you see fit. 从根本上讲,您只需要使行为可注射,然后就可以根据需要更改它。 Be-it by replacing the function doing the checking outright (the functional way) as I did above, or enabling an object to replace it (the OO way). 通过替换函数来进行完全检查(功能方法),就像我在上面所做的那样,或者使对象能够替换它(OO方法)。

Order them in order of likelihood (so if >400 is most common, check for that first, and if x<200 is next most common, check for that, etc.) The example code is in order of increasing boundaries. 按照可能性的顺序对它们进行排序(因此,如果> 400是最常见的,请首先进行检查,如果x <200是次最常见的,请进行检查,等等。)示例代码按边界递增的顺序进行。

Next, your code doesn't show it and you just imply it, this is in a loop. 接下来,您的代码没有显示它,而只是暗示它,这是一个循环。 (And if it isn't a loop, then this isn't a perf issue of interest) You could try fancy loops like Duff's device. (而且,如果这不是循环,那么这也不是关注的性能问题)。您可以尝试像Duff的设备那样的奇特循环。

And figuring out what code can be changed to use more native API's is going to make a magical difference, whereas code optimizations like this will likely make only a marginal difference. 并且弄清楚可以更改哪些代码以使用更多的本机API将会产生神奇的变化,而像这样的代码优化可能只会产生很小的变化。

If you want it to be dynamic, you could always have a collection of conditions associated with actions and as soon as executed, these gets removed from the collection. 如果希望它是动态的,则始终可以拥有与动作相关联的条件的集合,并且一旦执行,这些条件就会从集合中删除。 However, I doubt it will lead to faster code execution, but you would have to create a jsperf test to know for sure. 但是,我怀疑它会导致更快的代码执行,但是您必须创建一个jsperf测试才能确定。

DEMO: http://jsfiddle.net/a2ZEj/1/ 演示: http : //jsfiddle.net/a2ZEj/1/

function doSomethingA() {}
function doSomethingB() {}

var doOperation = (function doOperation() {
    var operations = [
        {
            check: function (someArg) {
                return someArg > 100;
            },
            exec: doSomethingA
        },
        {
            check: function (someArg) {
                return someArg > 100 && someArg < 200;
            },
            exec: doSomethingB
        }
    ];

    return function (someArg) {
        var i = 0,
            len = operations.length,
            item;

        for (; i < len; i++) {
            if ((item = operations[i]).check(someArg)) {
                item.exec();
                operations.splice(i, 1);
                console.log('executed ' + item.exec.name);
                return;
            }
        }
    };
})();

doOperation(101); //calls doSomethingA
doOperation(101); //calls doSomethingB
doOperation(101); //does nothing

You can create a method as below and create dynamic conditions 您可以创建如下方法并创建动态条件

function buildCond(lhv1,rhv1,lhv2,rhv2) 
{
    var condition1,condition2;
    condition1 = condition2 = '';
    if(rhv1 !== -1){
        condition1 =  lhv1 + " == " + rhv1 + " && ";
    } 
    if(rhv2 !== -1){
        condition2 =  lhv2 + " == " + rhv2 + " && ";
    }
    return condition1 + condition2;
}

And then call this method with eval to execute

if(eval(buildCond(var1,value1,var2,value2)) === true){
    //do stuff
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JavaScript可以重写自己吗? - Is it possible for a JavaScript to rewrite itself? JavaScript:是否可以迭代OWN变量? - JavaScript: Is it possible to iterate your OWN variables? 是否可以重写JavaScript的apply函数? - Is it possible to rewrite JavaScript's apply function? 是否可以使用Javascript动态创建变量 - Is it possible to create variables dynamically with Javascript 使用图片网址为图片动态添加替代文字,可以吗? - dynamically add alternate text for your Image using the image URL is it possible? Javascript:是否可以让“dynamicListener”文件访问您的主 javascript 文件? - Javascript: Is it possible to give a "dynamicListener" file access to your main javascript file? 动态和永久地向页面添加元素 - Javascript / jQuery - Dynamically and Permanently Adding an Element to Your Page - Javascript/jQuery Javascript:可以动态创建多维数组吗? - Javascript: possible to dynamically create a multidimensional array? 是否可以向 JavaScript 对象添加动态命名的属性? - Is it possible to add dynamically named properties to JavaScript object? 是否可以使用Javascript动态修改作为资源加载的SVG? - Is it possible to dynamically modify an SVG loaded as a resource with Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM