I'm trying to change the context for jQuery's $.each
method. What did I miss?
$.each.call(this, [1,2,3], function(){
console.log(this); // expecting to see the window object
});
var foo = { bar: 1 };
$.each.call(foo, [1,2,3], function(){
console.log(this); // expecting to see the foo object
});
http://jsfiddle.net/53jhrbh5/
$.each
uses call
and apply
internally to set the right this
value in the callback, something like callback.apply(obj[i])
, so it uses the array for the this
value, and calling the method with call
won't change that.
It works something like this
function each(obj, callback, args) {
var value, i = 0,
length = obj.length,
isArray = isArraylike(obj);
if (args) {
if (isArray) {
for (; i < length; i++) {
value = callback.apply(obj[i], args);
}
} else {
for (i in obj) {
value = callback.apply(obj[i], args);
}
}
}
return obj;
}
See how it calls the callback, passing in each value from the passed array or object as the this
value, and that means you can't change it by calling the $.each
method differently, as it's this
value has nothing to do with the this
value of the callback function, that's being set by jQuery.
You could $.proxy
it, or bind()
it, but the easy way is just to use a variable
var self = this;
$.each(arr, function() {
console.log( self );
});
There are several ways to do this
1) Reference window from outside
var self = this;
$.each.call(this, [1,2,3], function(){
console.log(self); // expecting to see the window object
});
2) Bind the function to a particular scope
$.each.call(this, [1,2,3], function(){
console.log(this); // expecting to see the window object
}.bind(this));
3) Use ES6 arrow function which binds to current context (Can't use in most browsers without some 6->5 conversion)
$.each.call(this, [1,2,3], () => {
console.log(this); // expecting to see the window object
});
4) Just reference window directly
$.each.call(this, [1,2,3], () => {
console.log(window); // expecting to see the window object
});
Just use Function.bind
on the callback to specify what context you want the function to run in.
$.each([1,2,3], (function(){
console.log(this); // expecting to see the window object
}).bind(this));
Internally jQuery uses ThisBinding
modifiers like apply
, call
. So, this
will always be a Number
, unless you specify the context of the callback to be run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With