javascript - 在 JavaScript 中将多组参数作为数组传递是否比多个函数调用更快?

标签 javascript jquery arrays arguments

在对使用不同参数多次调用同一函数感到有点不舒服之后(如下面代码的 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 () {

这里有两个问题:

  1. 您正在使用隐式全局变量。
  2. 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/

相关文章:

javascript - 在网站的新页面上保持事件菜单打开

java - 如何使用方法返回用户输入值的 double 组?

php从数组中取消设置与preg_match函数匹配的键

javascript - 没有动态参数的jquery ajax回调函数

javascript - AngularJS ng-repeat 重新渲染

javascript - 在 react 中,如何从列表中删除特定项目

javascript - 为什么selector.text会得到一个内部函数值?

javascript - 如何对通过 jQuery.append() 方法加载的 HTML 数据使用 JavaScript 函数?

javascript - 在 Phonegap 模拟器/iPhone 中解析 JSON 与通过浏览器解析 JSON

java - 检查数组中是否存在随机数