在对使用不同参数多次调用同一函数感到有点不舒服之后(如下面代码的 dom 就绪部分所示),我决定通过迭代数组来测试传递该函数的参数(如mouse_function_two
所示)。令我惊讶的是,我发现 mouse_function_two
运行速度要快得多。
我的问题是,mouse_function_two
是否会被认为比 mouse_function_one
更好的 JavaScript 实践?
注意:我有点担心我可能没有正确使用 firebugs console.time 实用程序!
初步尝试
function mouse_function_one (hover_selector, class_name, add_link) {
hover_item = $(hover_selector)
hover_item.each(function(){
$(this).hover(
function () {
$(this).addClass(class_name);
if ( add_link == true ) {
$(this).click(function(){
var href = $(this).find('a').attr('href');
window.location.href = href;
});
}
else return false;
},
function () {
$(this).removeClass(class_name);
});
});
}
第二次(更快)尝试:
function mouse_function_two (args) {
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 () {
$(this).addClass(class_name);
if ( add_link == true ) {
$(this).click(function(){
var href = $(this).find('a').attr('href');
window.location.href = href;
});
}
else return false;
},
function () {
$(this).removeClass(class_name);
});
});
}
}
客户端代码:
// on dom ready
$(function(){
console.time('f1');
mouse_function_one('#newsletter .right', 'hovered', true);
mouse_function_one('.block-couple div.right', 'hovered', false);
mouse_function_one('.bulletin', 'selected', true);
console.timeEnd('f1'); //speed is calculated as 104ms
args = [];
args[0] = ['#newsletter .right', 'hovered', true];
args[1] = ['.block-couple div.right', 'hovered', false];
args[2] = ['.bulletin', 'selected', true];
console.time('f2');
mouse_function_two(args);
console.timeEnd('f2'); //speed is calculated as 10ms
});
最佳答案
如果第二个例程更快,可能是因为它没有执行其应该执行的操作。看看这个片段:
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 () {
这里有两个问题:
- 您正在使用隐式全局变量。
- JavaScript 中的 block 不会引入新的作用域。
其中任何一个都会导致相同的错误,它们一起只会双重确定它会发生:为 hover()
事件处理函数创建的闭包仅包含最终循环的值迭代。最终调用这些处理程序时,class_name
将始终为 "selected"
,并且 add_link
将始终为 true
。相反,您的原始函数每次都会使用一组不同的参数进行调用,这些参数将由事件处理程序在函数的作用域中捕获,从而按预期工作。
至于风格……很乱。您将整个函数体封装在一个循环中,删除了描述性参数,并使函数的调用变得非常复杂。
幸运的是,您可以解决我上面指出的问题,简化函数,并一次性简化它的调用方式:
// 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');
请注意,这些更改很可能会消除与您最初尝试相比的任何速度差异,因为代码实际上执行了相同的操作,但增加了打包然后提取参数的步骤...
关于javascript - 在 JavaScript 中将多组参数作为数组传递是否比多个函数调用更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1413230/