如何传递可变数量的参数以及回调函数?

时间:2010-05-27 15:22:16

标签: javascript function parameters callback arguments

我正在使用一个函数来延迟加载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,然后在完成加载后调用我需要的任何函数(使用它需要的任何参数)。

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

这里的一般想法是创建一个闭包或lambda。在某种程度上,您可以将它们视为预先加载了可以调用的参数的函数。这有时也被称为代表。

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

然后,对于你的其他情况

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

更多阅读closures

答案 1 :(得分:2)

您可以在回调中使用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”。

答案 2 :(得分:2)

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

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

example('any', 'number', 'of', 'arguments);