【问题标题】:How do I pass a variable number of parameters along with a callback function?如何将可变数量的参数与回调函数一起传递?
【发布时间】:2010-05-27 15:22:15
【问题描述】:

我正在使用一个函数来延迟加载Sizzle 选择器引擎(由 jQuery 使用):

var sizzle_loaded;

// load the Sizzle script
function load_sizzle(module_name) {

  var script;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    gather_content(module_name);
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      gather_content(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

我设置了 onloadonreadystatechange 事件处理程序,以及 sizzle_loaded 标志,以便在 Sizzle 加载后立即调用另一个函数 (gather_content())。所有这些都需要以跨浏览器的方式进行。

到目前为止,我的项目只需要在脚本中的某一点延迟加载 Sizzle,因此我可以将 gather_content() 函数调用硬编码到 load_sizzle() 函数中。

但是,我现在需要在脚本中的两个不同点延迟加载 Sizzle,并在加载后调用不同的函数。我的第一直觉是修改函数以接受回调函数:

var sizzle_loaded;

// load the Sizzle script
function load_sizzle(module_name, callback) {

  var script;

  // load Sizzle script and set up 'onload' and 'onreadystatechange' event
  // handlers to ensure that external script is loaded before dependent
  // code is executed
  script = document.createElement('script');
  script.src = 'sizzle.min.js';
  script.onload = function() {
    sizzle_loaded = true;
    callback(module_name);
  };
  script.onreadystatechange = function() {
    if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
        !sizzle_loaded) {
      sizzle_loaded = true;
      callback(module_name);
    }
  };

  // append script to the document
  document.getElementsByTagName('head')[0].appendChild(script);

}

那么,我可以这样称呼它:

load_sizzle(module_name, gather_content);

但是,我需要使用的另一个回调函数比gather_content() 需要更多的参数。

如何修改我的函数,以便我可以指定可变数量的参数,以与回调函数一起传递?或者,我是不是走错了路?

最终,我只想加载 Sizzle,然后在加载完成后调用我需要的任何函数(使用它需要的任何参数)。

感谢您的帮助!

【问题讨论】:

    标签: javascript function parameters callback arguments


    【解决方案1】:

    这里的总体思路是创建一个闭包或 lambda。在某种程度上,您可以将它们视为一个预先加载了可供调用的参数的函数。这有时也称为委托。

    load_sizzle( module_name, function()
    {
      gather_content();
    });
    

    那么,对于你的其他情况

    load_sizzle( module_name, function()
    {
      some_other_function( param1, param2 );
    });
    

    更多阅读closures

    【讨论】:

      【解决方案2】:

      您可以使用 arguments 数组来获取传递给函数的所有参数。

      function example() {
      for( var i = 0; i < arguments.length; i++ ) {
          alert('argument ' + i + ' ' + arguments[i]);
      }
      }
      
      example('any', 'number', 'of', 'arguments);
      

      【讨论】:

        【解决方案3】:

        你可以在回调上使用apply方法:

        function load_sizzle(module_name, callback,args) {
        
          var script, args=args || []; //Be sure that an array is passed
        
          // load Sizzle script and set up 'onload' and 'onreadystatechange' event
          // handlers to ensure that external script is loaded before dependent
          // code is executed
          script = document.createElement('script');
          script.src = 'sizzle.min.js';
          script.onload = function() {
            sizzle_loaded = true;
            callback.apply(window,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
          };
          script.onreadystatechange = function() {
            if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
                !sizzle_loaded) {
              sizzle_loaded = true;
              callback(module_name);
            }
          };
        
          // append script to the document
          document.getElementsByTagName('head')[0].appendChild(script);
        
        }
        

        然后作为 load_sizzle 的第三个参数,您可以为函数传递一组额外参数。

        你也可以用这个来改进代码:

        function load_sizzle(module_name, callback,args,bind) {
        
          var script, args=args || [],bind=bind || window;
        
          // load Sizzle script and set up 'onload' and 'onreadystatechange' event
          // handlers to ensure that external script is loaded before dependent
          // code is executed
          script = document.createElement('script');
          script.src = 'sizzle.min.js';
          script.onload = function() {
            sizzle_loaded = true;
            callback.apply(bind,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user
          };
          script.onreadystatechange = function() {
            if ((script.readyState === 'loaded' || script.readyState === 'complete') &&
                !sizzle_loaded) {
              sizzle_loaded = true;
              callback(module_name);
            }
          };
        
          // append script to the document
          document.getElementsByTagName('head')[0].appendChild(script);
        
        }
        

        通过这种方式,参数号 4(如果指定)可以是一个对象,它将是您传递的回调中的“this”。

        【讨论】:

        • 非常感谢,mck89!我最终选择了 Peter Bailey 的解决方案(对我来说似乎更优雅,并且需要更少的代码更改)。但是,FWIW,您的回答本身就很有教育意义。再次感谢!
        猜你喜欢
        • 1970-01-01
        • 2010-11-28
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 2013-02-07
        • 2015-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多