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

有些话、适合烂在心里 提交于 2019-12-22 07:13:09

问题


I have added the following method to the Array prototype:

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

In the same file, after the above code, I have the following jQuery plugin:

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

In order to use this jQuery plugin, my code would look something like:

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

However, the browser throws an error on the "arguments.foreach(...." line of the jQuery plugin, stating simply that

Object # has no method 'foreach'

Yet the foreach method works in other places of my code. Why is it undefined within this jQuery plugin?


回答1:


It doesn't work because arguments isn't an array. Its an (array-like) arguments object.

Explanation from Mozilla

You can convert it to an array using slice in modern browsers (and by actually looping in IE).

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



回答2:


arguments is not an array, but an object. For example it provides properties such as arguments.callee and arguments.caller.

You can use foreach of the Array prototype by calling apply on it (cf. The JavaScript arguments object…and beyond):

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

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



回答3:


You need to turn the arguments object into an array

Try this:

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



回答4:


To convert the arguments to an array, you can use the jQuery.makeArray(arguments) too...

http://api.jquery.com/jQuery.makeArray/



来源:https://stackoverflow.com/questions/9053536/why-does-this-change-to-the-array-prototype-not-work-in-my-jquery-plugin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!