在$.each()中更改上下文环境

6

我试图为jQuery的$.each方法改变上下文。我错过了什么?

$.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/


“this” 将始终是其中一个数字。 - Venkata Krishna
3个回答

5
有几种方法可以实现这一点。
1)从外部引用窗口。
var self = this;
$.each.call(this, [1,2,3], function(){
    console.log(self); // expecting to see the window object
});

2) 将函数绑定到特定的作用域

$.each.call(this, [1,2,3], function(){
    console.log(this); // expecting to see the window object
}.bind(this));

3) 使用ES6箭头函数绑定当前上下文(在大多数浏览器中无法使用,需要进行一些6->5的转换)

$.each.call(this, [1,2,3], () => {
   console.log(this); // expecting to see the window object
});

4) 直接引用窗口

$.each.call(this, [1,2,3], () => {
   console.log(window); // expecting to see the window object
});

1
完整答案!只是缺少支持旧浏览器的jQuery方法:$.each([1,2,3], $.proxy(function(){ console.log(this); // 预计会看到window对象 }, this)); - A. Wolff

5

$.each 在内部使用 callapply 来设置回调函数中正确的 this 值,类似于 callback.apply(obj[i]),因此它使用数组作为 this 值,并且使用 call 调用方法不会改变这一点。

它的工作原理类似于这样

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

看看它如何调用回调函数,将传递的数组或对象中的每个值作为“this”值传递,并且这意味着您无法通过以不同方式调用“$.each”方法来更改它,因为它的“this”值与回调函数的“this”值没有关系,这是由jQuery设置的。你可以使用$.proxybind(),但简单的方法就是使用一个变量。
var self = this;

$.each(arr, function() {
     console.log( self );
});

谢谢,这正是我想知道的。 - filur

3
只需要在回调函数中使用Function.bind来指定你想要函数运行的上下文即可。
$.each([1,2,3], (function(){
    console.log(this); // expecting to see the window object
}).bind(this));

在内部,jQuery使用applycallThisBinding修饰符。因此,除非您指定回调的上下文来运行,否则this将始终是一个Number


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接