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