在JavaScript中作为数组传递多组参数是否比多个函数调用更快?
在对同一个函数的多个调用以及不同的参数(如下面代码的dom就绪部分所示)感到有点不舒服之后,我决定通过迭代数组来测试传递该函数的参数(如在JavaScript中作为数组传递多组参数是否比多个函数调用更快?,javascript,jquery,arrays,arguments,Javascript,Jquery,Arrays,Arguments,在对同一个函数的多个调用以及不同的参数(如下面代码的dom就绪部分所示)感到有点不舒服之后,我决定通过迭代数组来测试传递该函数的参数(如mouse\u function\u two所示)。令我惊讶的是,我发现mouse\u function\u two运行得相当快 我的问题是,mouse\u function\u two会被认为比mouse\u function\u one更好的JavaScript实践吗 注意:我有点担心我可能没有正确使用Firebug console.time实用程序 初步尝
mouse\u function\u two
所示)。令我惊讶的是,我发现mouse\u function\u two
运行得相当快
我的问题是,mouse\u function\u two
会被认为比mouse\u function\u one
更好的JavaScript实践吗
注意:我有点担心我可能没有正确使用Firebug console.time实用程序
初步尝试
第二次(更快)尝试:
这是一段瓶颈代码吗?使用数组作为参数会使您面临一系列错误,命名参数可以保护您免受这些错误的影响。第二段代码读起来相当糟糕,如果还没有,经过一段时间,将被证明是一个完全需要调试的错误。所以,除非很关键,否则保持理智。只有当它真的是有问题的代码时,你才应该开始扔掉一些合理的语言特性来提高速度
编辑:我看代码越多,你的基准测试就越不平衡。有许多事情你没有考虑过,可能导致一个不同的结论,比如在单个调用中重复的方法调用的成本,以及填充数组等在第二种情况下没有基准。 < P>我会考虑在你的情况下传递一个JSON对象。像ExtJs和JQuery这样的框架严重依赖于它们,因为这样做给了您很大的灵活性(尤其是随着API的发展),并且它允许您在单个对象中打包大量数据
function mouse_function_three (args) { ... }
args看起来像
[{'hover_selector': ... , 'class_name': ... , 'add_link': ...}, {'hover_selector': ... , 'class_name': ... , 'add_link': ...}, ... ]
您甚至可以通过为每个对象的属性指定默认属性来扩展此功能,例如:
{
'default_hover_selector': 'asdf',
'default_class': 'asdf',
'add_link: false,
'items': [{'hover_selector': ... , 'class_name': ... , 'add_link': ...}, {'hover_selector': ... , 'class_name': ... , 'add_link': ...}, ... ]
}
我认为此解决方案将为您提供所需的性能和直观性(甚至是一个词)。如果第二个例程更快,可能是因为它没有完成它应该做的事情。请看一下这个片段:
for (var i=0; i < args.length; i++) {
hover_selector = $(args[i][0]);
class_name = args[i][1];
add_link = args[i][2];
hover_item = $(hover_selector)
hover_selector.each(function(){
$(this).hover(
function () {
然后,您可以这样称呼这个新例程:
console.time('f3');
mouse_function_three(
{hover_selector: '#newsletter .right', class_name: 'hovered', add_link: true},
{hover_selector: '.block-couple div.right', class_name: 'hovered', add_link: false},
{hover_selector: '.bulletin', class_name: 'selected', add_link: true}
);
console.timeEnd('f3');
请注意,这些更改可能会很好地消除与初始尝试的任何速度差异,因为代码有效地完成了同样的事情,但打包和提取参数的附加步骤…肯定取决于JS引擎。为什么不自己做个基准测试看看呢?这里的时间开销可能是函数调用吗?根据第三个代码块中的时间,方法f1看起来是最容易获胜的。输入错误?谢谢spender,我确实输入了一个错误-现在已经输入了,是的,如上所述,我不确定我使用console的完整性。时间,我现在已经做了20次测试,很清楚时间现在准确地表示了代码,但不确定比较的公平性。我在决定使用数组之前尝试使用对象,但我不太确定该怎么做,这种技术很吸引人,特别是对于默认属性。我来试一试。谢谢Shog9,这是我关于stackoverflow的第一个问题,我对这里的回答和细节感到惊讶,这个答案真的一针见血,我应该编辑这个问题,忘记速度,选择最佳实践,这在你的回答中是显而易见的。尽管如此,我还是要把大部分回答的背景删掉。为了记录在案,这个时间是94毫秒,尽管我认为这并不重要,因为我们将它与不可靠的代码进行比较,而(我方面)没有完全理解如何正确地对这些函数进行基准测试。
{
'default_hover_selector': 'asdf',
'default_class': 'asdf',
'add_link: false,
'items': [{'hover_selector': ... , 'class_name': ... , 'add_link': ...}, {'hover_selector': ... , 'class_name': ... , 'add_link': ...}, ... ]
}
for (var i=0; i < args.length; i++) {
hover_selector = $(args[i][0]);
class_name = args[i][1];
add_link = args[i][2];
hover_item = $(hover_selector)
hover_selector.each(function(){
$(this).hover(
function () {
// For starters, I've eliminated explicit parameters completely.
// args wasn't descriptive, and all JavaScript functions have an implicit
// arguments array already - so let's just use that.
function mouse_function_three () {
// use jQuery's array iteration routine:
// this takes a function as an argument, thereby introducing scope and
// avoiding the problem identified previously
$.each(arguments, function() {
var class_name = this.class_name;
var add_link = this.add_link;
var selected = $(this.hover_selector);
// no need to use selected.each() - jQuery event binding routines
// always bind to all selected elements
selected.hover(function() {
$(this).addClass(class_name);
},
function() {
$(this).removeClass(class_name);
});
// bring this out of the hover handler to avoid re-binding
if ( add_link ) {
$(selected).click(function(){
var href = $(this).find('a').attr('href');
window.location.href = href;
});
}
}); // each set of arguments
}
console.time('f3');
mouse_function_three(
{hover_selector: '#newsletter .right', class_name: 'hovered', add_link: true},
{hover_selector: '.block-couple div.right', class_name: 'hovered', add_link: false},
{hover_selector: '.bulletin', class_name: 'selected', add_link: true}
);
console.timeEnd('f3');