关于javascript:为什么这个更改为Array原型在我的jQuery插件中不起作用?

Why does this change to the Array prototype not work in my jQuery plugin?

我在阵列原型中添加了以下方法:

1
2
3
4
5
6
Array.prototype.foreach = function(func){
    for(var i = 0; i < this.length; i++){
        if(!func(this[i]) === false) break; //return false from func in order to break the loop
    }
    return this;
}

在同一个文件中,在上述代码之后,我有以下jquery插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jQuery.fn.addClassForEvents = function(){

    var that = this;

    arguments.foreach(function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}

为了使用这个jquery插件,我的代码看起来像:

1
$('div').addClassForEvents(['mouseenter', 'mouseleave']);

但是,浏览器在jquery插件的"arguments.foreach(……"行上抛出一个错误,简单地声明

Object # has no method 'foreach'

然而,foreach方法在我的代码的其他地方也有效。为什么在这个jquery插件中没有定义?


它不起作用,因为参数不是数组。它是一个(类似数组的)参数对象。

Mozilla的解释

您可以在现代浏览器中使用slice将其转换为数组(实际上也可以通过在IE中循环)。

1
var argArray = Array.prototype.slice.call(arguments)


arguments不是数组,而是一个对象。例如,它提供诸如arguments.calleearguments.caller之类的属性。

您可以通过在数组原型上调用apply来使用foreach(参见javascript arguments object…及更高版本):

Since all the methods of Array.prototype are designed to be generic they can be easily applied to the array-compatible arguments object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jQuery.fn.addClassForEvents = function(){

    var that = this;

    [].foreach.apply(arguments, (function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}


您需要将arguments对象转换为数组

试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jQuery.fn.addClassForEvents = function(){

    var that = this, arg = Array.prototype.slice.call(arguments);

    arg.foreach(function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}

要将arguments转换为数组,也可以使用jQuery.makeArray(arguments)

http://api.jquery.com/jquery.makearray/