在javascript中,定义函数内联与将其作为引用传递的权衡是什么?

时间:2011-07-20 23:11:38

标签: function-pointers javascript

所以,假设我有一大堆要附加事件监听器的元素。例如。我想让每一行在点击时变成红色的表格。

所以我的问题是哪一个是最快的,哪个使用最少的内存。我知道这是(通常)权衡,所以我想知道每个人的最佳选择。

使用表示例,假设有一个所有行元素的列表,“rowList”:

选项1:

for(var r in rowList){
     rowList[r].onclick = function(){ this.style.backgroundColor = "red" };
}

我的直觉是,这是最快的,因为只有少一个指针调用,但是内存最多,因为每个行列表都有自己的函数副本,如果onclick函数很大,这可能会变得严重。

选项2:

function turnRed(){
     this.style.backgroundColor = "red";
}
for(var r in rowList){
     rowList[r].onclick = turnRed;
}

我猜这将比上面的那个慢一点(哦不,再多一个指针取消引用!)但内存密集程度要低得多,因为浏览器只需要跟踪一个副本功能。

选项3:

var turnRed = function(){
     this.style.backgroundColor = "red";
}
for(var r in rowList){
     rowList[r].onclick = turnRed;
}

我认为这与选项2相同,但我只是想把它扔出去。对于那些想知道这和选项2之间区别的是:JavaScript differences defining a function

奖金部分:Jquery

同样的问题:

$('tr').click(function(){this.style.backgroundColor = "red"});

对战:

function turnRed(){this.style.backgroundColor = "red"};
$('tr').click(turnRed);

var turnRed = function(){this.style.backgroundColor = "red"};
$('tr').click(turnRed);

2 个答案:

答案 0 :(得分:5)

这是你的答案:

http://jsperf.com/function-assignment

选项2更快,占用内存更少。原因是选项1为循环的每次迭代创建一个新的函数对象。

答案 1 :(得分:2)

就内存使用而言,Option 1正在为数组中的每一行创建一个独特的函数闭包。因此,此方法将使用比Option 2Option 3更多的内存,它只创建一个函数,然后传递对它的引用。

出于同样的原因,我也希望Option 1是三者中最慢的。当然,实际性能和内存使用方面的差异可能非常小,但如果你想要最有效的那个,那么选择Option 2Option 3(它们几乎都是同样,两者之间唯一真正的区别是turnRed可见的范围。

对于jQuery,所有三个选项都具有相同的内存使用和性能特征。在每种情况下,无论是否内联定义,都要创建并向jQuery传递单个函数引用。

在您的问题中没有提到的一个重要注意事项是,使用大量内联函数可以快速将代码变为难以理解的混乱并使其更难维护。这里没什么大不了的,因为你的函数中只有一行代码,但作为一般规则,如果你的函数包含超过2-3行,最好避免内联定义它。而是将其定义为Option 2Option 3,然后传递对它的引用。