我一直想知道,在Javascript中使用命名函数和匿名函数之间是否存在性能差异?
for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = function() { // do something }; }
VS
function myEventHandler() { // do something } for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = myEventHandler; }
第一个是更整洁,因为它不会使用很少使用的函数使代码混乱,但重要的是你多次重新声明该函数是否重要?
这里的性能问题是在循环的每次迭代中创建新函数对象的成本,而不是使用匿名函数的事实:
for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = function() { // do something }; }
您正在创建一千个不同的函数对象,即使它们具有相同的代码体并且没有绑定到词法范围(闭包).另一方面,以下似乎更快,因为它只是在整个循环中为数组元素分配相同的函数引用:
function myEventHandler() { // do something } for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = myEventHandler; }
如果您在进入循环之前创建匿名函数,那么只有在循环内部时才将对它的引用分配给数组元素,您会发现与命名函数版本相比,没有任何性能或语义差异:
var handler = function() { // do something }; for (var i = 0; i < 1000; ++i) { myObjects[i].onMyEvent = handler; }
简而言之,使用匿名命名函数没有可观察到的性能成本.
顺便说一下,从上面看,两者之间没有区别:
function myEventHandler() { /* ... */ }
和:
var myEventHandler = function() { /* ... */ }
前者是函数声明,而后者是匿名函数的变量赋值.尽管它们似乎具有相同的效果,但JavaScript确实对它们的处理方式略有不同.为了理解差异,我建议阅读" JavaScript函数声明模糊 ".
任何方法的实际执行时间主要取决于浏览器的编译器和运行时的实现.有关现代浏览器性能的完整比较,请访问JS Perf站点
这是我的测试代码:
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)); }
结果:
测试1:142ms测试2:1983ms
似乎JS引擎无法识别它在Test2中的功能是相同的,并且每次都编译它.