为什么这个对于Array原型的改变在我的jQuery插件中不起作用?

11 浏览
0 Comments

为什么这个对于Array原型的改变在我的jQuery插件中不起作用?

我已经将以下方法添加到了Array原型中:\n

Array.prototype.foreach = function(func){
    for(var i = 0; i < this.length; i++){
        if(!func(this[i]) === false) break; //从func返回false以终止循环
    }
    return this;
}

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

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;
}

\n为了使用这个jQuery插件,我的代码会像这样:\n

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

\n然而,浏览器在jQuery插件的\"arguments.foreach(....\"行抛出了一个错误,简单地说:\n

\n对象#没有foreach方法\n

\n然而,foreach方法在我的其他代码中是可用的。为什么在这个jQuery插件中未定义?

0
0 Comments

为什么我的jQuery插件中的Array原型更改不起作用?

问题原因:需要将arguments对象转换为数组。

解决方法:

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对象转换为数组,使其可以正常工作。

0
0 Comments

问题的原因是在这段代码中使用了apply来调用foreach方法,但是arguments不是一个数组,而是一个对象。解决方法是将arguments转换成一个数组,然后再调用foreach方法。

解决方法代码如下:

jQuery.fn.addClassForEvents = function(){
    var that = this;
    [].forEach.call(Array.prototype.slice.call(arguments), (function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });
    return this;
}

0
0 Comments

问题出现的原因是arguments不是一个数组,它是一个类似数组的arguments对象。解决方法是将arguments对象转换成数组。在现代浏览器中,可以使用slice方法来实现转换(在IE中需要使用循环来转换)。

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

在IE中也可以使用slice方法来转换。可能是因为我有一个通用的函数,其中包含一些IE不喜欢调用slice方法的类似数组对象。

0