Javascript 使用匿名函数是否会影响性能?

Javascript 使用匿名函数是否会影响性能?,javascript,performance,optimization,Javascript,Performance,Optimization,我一直在想,在Javascript中使用命名函数和匿名函数之间是否存在性能差异 for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = function() { // do something }; } for(变量i=0;i

我一直在想,在Javascript中使用命名函数和匿名函数之间是否存在性能差异

for (var i = 0; i < 1000; ++i) {
    myObjects[i].onMyEvent = function() {
        // do something
    };
}
for(变量i=0;i<1000;++i){
myObjects[i].onMyEvent=function(){
//做点什么
};
}
vs

函数myEventHandler(){
//做点什么
}
对于(变量i=0;i<1000;++i){
MyObject[i].onMyEvent=myEventHandler;
}

第一个更整洁,因为它不会让很少使用的函数把代码弄得乱七八糟,但多次声明该函数是否重要?

作为一般设计原则,应该避免多次实现相同的代码。相反,您应该将公共代码提升到一个函数中,并从多个位置执行该函数(通用、经过良好测试、易于修改)

如果(与您从问题中推断的情况不同)您只声明了一次内部函数,并使用了一次该代码(并且在程序中没有其他相同的代码),那么一个匿名函数(这是一个猜测)可能会被编译器视为一个普通命名函数


它在特定情况下非常有用,但不应在许多情况下使用。

我不希望有太大的差异,但如果有差异,它可能会因脚本引擎或浏览器而异


如果您发现代码更容易查找,那么性能是一个不成问题的问题,除非您希望调用该函数数百万次。

在各种浏览器(尤其是IE浏览器)中,一定会使您的循环速度更快的是循环,如下所示:

for (var i = 0, iLength = imgs.length; i < iLength; i++)
{
   // do something
}
for(变量i=0,iLength=imgs.length;i
您已将任意1000放入循环条件中,但如果要遍历数组中的所有项,您将得到我的漂移。

以下是我的测试代码:

var dummyVar;
function test1() {
    for (var i = 0; i < 1000000; ++i) {
        dummyVar = myFunc;
    }
}

function test2() {
    for (var i = 0; i < 1000000; ++i) {
        dummyVar = function() {
            var x = 0;
            x++;
        };
    }
}

function myFunc() {
    var x = 0;
    x++;
}

document.onclick = function() {
    var start = new Date();
    test1();
    var mid = new Date();
    test2();
    var end = new Date();
    alert ("Test 1: " + (mid - start) + "\n Test 2: " + (end - mid));
}
var-dummyVar;
函数test1(){
对于(变量i=0;i<1000000;++i){
dummyVar=myFunc;
}
}
函数test2(){
对于(变量i=0;i<1000000;++i){
dummyVar=函数(){
var x=0;
x++;
};
}
}
函数myFunc(){
var x=0;
x++;
}
document.onclick=函数(){
var start=新日期();
test1();
var mid=新日期();
test2();
var end=新日期();
警报(“测试1:+(中间启动)+”\n测试2:+(中间结束));
}
结果:
测试1:142ms 测试2:1983ms

JS引擎似乎没有意识到它是Test2中的同一个函数,每次都编译它。

@nickf

不过,这是一个相当愚蠢的测试,您正在比较那里的执行和编译时间,这显然会消耗方法1(编译N次,取决于JS引擎)和方法2(编译一次)。我无法想象一个JS开发人员会通过试用期以这种方式编写代码

一种更现实的方法是匿名分配,因为实际上您正在为文档使用匿名分配。onclick方法更像下面的方法,它实际上稍微支持anon方法

使用与您类似的测试框架:


功能测试(m)
{
对于(变量i=0;i<1000000;++i)
{
m();
}
}
名为()的函数{var x=0;x++;}
var test1=命名;
var test2=function(){var x=0;x++;}
document.onclick=函数(){
var start=新日期();
测试(test1);
var mid=新日期();
试验(试验2);
var end=新日期();
警报(“测试1:+(中间启动)+”毫秒\n测试2:+(中间结束)+“毫秒”);
}

这里的性能问题是每次循环迭代时创建新函数对象的成本,而不是使用匿名函数的事实:

for (var i = 0; i < 1000; ++i) {    
    myObjects[i].onMyEvent = function() {
        // do something    
    };
}
以及:

前者是函数声明,而后者是匿名函数的变量赋值。尽管它们看起来可能有相同的效果,JavaScript对它们的处理却略有不同。要理解其中的区别,我建议阅读“.”


任何方法的实际执行时间在很大程度上取决于浏览器对编译器和运行时的实现。要全面比较现代浏览器的性能,请访问

参考几乎总是比它所指的东西慢。这样考虑-假设您想要打印1+1相加的结果。这更有意义:

alert(1 + 1);
$(a.button1).click(function(){alert('you clicked ' + this);});
$(a.button2).click(function(){alert('you clicked ' + this);});

我意识到这是一种非常简单的方式来看待它,但它是说明性的,对吗?仅当引用将被多次使用时才使用它-例如,以下哪个示例更有意义:

alert(1 + 1);
$(a.button1).click(function(){alert('you clicked ' + this);});
$(a.button2).click(function(){alert('you clicked ' + this);});


第二个是更好的练习,即使它有更多的台词。希望所有这些都有帮助。(jquery语法并没有让任何人失望)

是的!匿名函数比常规函数快。也许如果速度是最重要的。。。更重要的是代码重用,然后考虑使用匿名函数。

这里有一篇关于优化javascript和匿名函数的非常好的文章:

@nickf

(希望我的代表能发表评论,但我只是找到了这个网站)

我的观点是,命名/匿名函数与在迭代中执行+编译的用例之间存在混淆。正如我所说明的,anon+命名之间的差异本身可以忽略不计——我是说它的用例是错误的


这对我来说似乎很明显,但如果不是,我认为最好的建议是“不要做愚蠢的事情”(这个用例的持续块移动+对象创建就是其中之一),如果你不确定,请测试

匿名对象比命名对象快。但是调用更多函数的代价更高,并且在某种程度上超过了使用匿名函数所节省的成本。调用的每个函数都会添加到调用堆栈中,这会带来少量但不平凡的开销

但除非你在写encry
function myEventHandler() { /* ... */ }
var myEventHandler = function() { /* ... */ }
alert(1 + 1);
a = 1;
b = 1;
alert(a + b);
$(a.button1).click(function(){alert('you clicked ' + this);});
$(a.button2).click(function(){alert('you clicked ' + this);});
function buttonClickHandler(){alert('you clicked ' + this);}
$(a.button1).click(buttonClickHandler);
$(a.button2).click(buttonClickHandler);
// Variant 1: create once
function adder(a, b) {
  return a + b;
}
for (var i = 0; i < 100000; ++i) {
  var x = adder(412, 123);
}

// Variant 2: repeated creation via function statement
for (var i = 0; i < 100000; ++i) {
  function adder(a, b) {
    return a + b;
  }
  var x = adder(412, 123);
}

// Variant 3: repeated creation via function expression
for (var i = 0; i < 100000; ++i) {
  var x = (function(a, b) { return a + b; })(412, 123);
}