javascript – 如何编写一个接受和“转发”可变数量参数的JS函数?

如何编写一个接受可变数量参数的 Javascript函数,并将所有这些参数转发给其他匿名函数

例如,考虑触发事件的方法的场景:

function fireStartedEvent(a,b,c,d,e,f,g,...) {
    for(var i = 0; i < startedListeners.length; i++) {
        startedListeners[i](a,...);
    }
}

特别是因为我有一个生成这些消防方法的事件工厂,所以这些方法无需知道给定事件或其处理程序消耗了多少参数.所以我现在在7点硬连线(a到g).如果它没有,没问题.如果它已经存在,它们会被切断.我怎样才能捕获并传递所有参数?

谢谢.

(在这里使用jQuery或任何其他Javascript框架不是一个选项.)

解决方法

解决这个问题需要了解两个JavaScript概念.

一个是特殊的arguments局部变量,可用于访问函数参数而不知道它们的名称,它就像一个数组.但是,参数不是数组,而是“数组类似” – 具有名为0..n-1的属性,其中n是函数的参数数量和长度属性 – 对象.一个简单的演示用法可能是:

function f (a) { // can include names still,if desired
    // arguments instanceof Array -> false (exceptions to this?)
    var firstArg = arguments[0]
    // a === firstArg -> always true
    // iterate all arguments,just as if it were an Array:
    for (var i = 0; i < arguments.length; i++) {
        alert(i + " : " + arguments[i])
    }
}
f("a","b","c")

第二个特性是Function.apply,它将调用具有特定上下文的函数(在调用它时),其参数是由“数组类似”对象的扩展产生的.但是看1.

因此,把它放在一起:

function fireStartedEvent() {
    for(var i = 0; i < startedListeners.length; i++) {
        // jQuery will often pass in "cute" things,such as a element clicked
        // as the context. here we just pass through the current context,`this`,// as well as the arguments we received.
        var arg = Array.prototype.slice.call(arguments)
        startedListeners[i].apply(this,args)
    }
}

1虽然ECMAScript规范只调用“数组类似”对象,但Function.apply并不普遍使用“数组类似”对象,并且许多常见实现需要适当的Array对象. Function.apply链接的警告:

Note: Most browsers,including Chrome 14 and Internet Explorer 9,still do not accept array like objects and will throw an exception [if a non-Array object is passed]. [FireFox was fixed in version 4.]

值得庆幸的是,有一个相对简单的习惯用法将“数组类似”对象转换为数组(这很具有讽刺意味,因为Array.slice通常使用“数组类似”对象):

var args = Array.prototype.slice.call(arguments);

(然后args可以普遍用于Function.apply.)

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...