问题
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