为什么以及如何jQuery的`$(this)`引用正确的节点?

时间:2012-06-11 17:06:38

标签: javascript jquery this internals

我知道如何使用jQuery的$(this)选择器,我也了解Javascript中的OOP原理。我总是接受它只是有效,因为其他人实现了它,但我很想知道为什么以及如何它的工作原理。

$(function(){
   $('.foo').each(function(){
      console.log($(this));
   });
});

鉴于此代码。我知道$('.foo')找到一组HTML元素并返回一个 jQuery对象,它可以使用.each(...)迭代它们。然后each()方法的内部结构可能会调用闭包,它已作为参数传递。

但为什么this会引用闭包内的特定HTML元素?我一直认为this只会引用一个新的范围,只要它的包装已经使用new进行了实例化。如果this引用window,那么它会更加一致吗?

3 个答案:

答案 0 :(得分:8)

最后,您始终可以使用this.call在函数中强制.apply值。 jQuery做到了这一点;看看source of .each

if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
//                  ^ `this` value

这里,this值将设置为元素(object[i]),计数器(i)和元素作为参数传递给您的函数,即{ {1}}。

答案 1 :(得分:4)

它是具有类.foo的所有匹配元素的简单迭代,并使用.call/.apply调用内部函数。

检查.each实施http://james.padolsey.com/jquery/#v=git&fn=jQuery.each

请注意以下代码中的.call / .apply调用,以确保this.foo[i]

jQuery .each实现

function (object, callback, args) {
    var name, i = 0,
        length = object.length,
        isObj = length === undefined || jQuery.isFunction(object);
    if (args) {
        if (isObj) {
            for (name in object) {
                if (callback.apply(object[name], args) === false) {
                    break;
                }
            }
        } else {
            for (; i < length;) {
                if (callback.apply(object[i++], args) === false) {
                    break;
                }
            }
        }
    } else {
        if (isObj) {
            for (name in object) {
                if (callback.call(object[name], name, object[name]) === false) {
                    break;
                }
            }
        } else {
            for (; i < length;) {
                if (callback.call(object[i], i, object[i++]) === false) {
                    break;
                }
            }
        }
    }
    return object;
}

答案 2 :(得分:3)

“为什么”是因为jQuery(selector).each 定义的运作方式:

  

...在当前DOM元素的上下文中触发回调,因此关键字this引用该元素。

不需要这样做,但确实如此。 (有关“如何”使用的机制,请参阅Function.callFunction.apply。)

快乐的编码!