不要在循环中使用函数 Javascript

问题描述 投票:1回答:2

我明白这样的问题可能有三百个,我也明白为什么不要。如果我们在循环说一个常规的for循环,每一次迭代我们都会创建一个匿名函数表达式,这就会使用更多的内存。相反,我们把函数放在循环之外,从而给它取了个名字叫

匿名函数迭代示例

var elements = document.getElementsByClassName('elementName');
for(var i=0; i < elements.length; i++ )
{
  elements[i].addEventListener('click',function(e){
    console.log(e);
  });
}

命名函数迭代示例

function handleClickEvents(e) {
   console.log(e);
}

var elements = document.getElementsByClassName('elementName');
for(var i=0; i < elements.length; i++ )
{
  elements[i].addEventListener('click',handleClickEvents);
}

这里的问题是想向别人证明这个逻辑,说实话我的jsperfs完全在反驳我。请你自己看看测试结果 此处

那么是jsPerf只是计算错误,还是这只是一个完全破灭的神话?我看到,通过运行匿名函数作为我的 eventListener 函数,我获得了比梯子更快的速度。

有谁能启发我,这里有什么问题,为什么如果我们用第一个例子获得了更多的速度,我甚至要从第二个版本中多出两行?

javascript loops dom-events event-listener
2个回答
2
投票

你不应该担心性能问题--我很难想象你要添加数百万个事件监听器。

第二种选择(指定一个函数引用)的优越性在于,函数一旦被定义,就有可能在其他地方使用。它需要更少的 });因此,不容易出现错别字。也许更重要的是,它可能更具可读性。让我们以传递一个函数给 Array#filter,检查文件名是否为jpg。

names.filter(function(name) { 
    return /\.jpg$/i.test(name);
});

vs. 检验方法

function isJpeg(name) { return /\.jpg$/i.test(name); }

names.filter(isJpeg);

如果你把这些方法链在一起,好处就会变得更加明显。

names . filter(isJpeg) . map(makeThumbnail) . forEach(uploadJpg);

最后,这其实并不重要,归根结底是个人的喜好,但有一点是很清楚的,那就是性能问题不应该成为你做出决定的动力,除非在非常特殊的情况下。一个好的一般规则是在行内编写非常短的一次性函数。对于ES6和箭头函数,更多的函数可以是 "非常短 "的,是内联的候选函数。

顺便说一下,即使在内联写函数时,给它起个名字也是个好主意。

names.filter(function isJpeg(name) { 

这样做有几个好处 首先,这是文档注释的一种形式,有助于人们阅读你的代码。第二,大多数调试器和堆栈跟踪会更好地报告函数的情况。大多数minifiers会删除这个名字,所以对生产没有影响。


2
投票

我相信你的比较是有缺陷的。如果你要把代码反过来。把匿名函数放在对比的后面。就会比较慢。(http:/jsperf.combest-event-listener-practice5。). 后期的代码总是会比较慢,因为之前已经做了那么多绑定。

© www.soinside.com 2019 - 2024. All rights reserved.