鉴于以下常见情况:
console.log(this); // window or any parent object
$('.selector').on('click', function(event) {
console.log(this); // clicked DOM element
});
var myFunc = function() {
console.log(this); // window or parent object
}
从版本1.3开始,jQuery在绑定事件处理程序event.currentTarget === this
时添加了event.currentTarget
,那么实际上有理由操纵this
并切换上下文吗?这种行为通常不会违反“不改变关键字值”的潜规则。 (比如undefined = 'not defined'
)?
这个"功能"当我们需要将原始this
缓存在self
之类的变量中或使用jQuery.proxy
之类的帮助程序将上下文重新分配给事件处理程序时,jQuery会使很多OOP效率降低且难以理解imho
我的问题:这只是早期jQuery实现的遗留还是有一个我看不到的实际好处(除了可能比访问event.currentTarget
获取元素更方便的方式...) ?
答案 0 :(得分:4)
假设您有一个带有某些方法的对象:
var object = {
click: function() {
alert(this.property);
},
property: "Hello World"
}
您可以致电object.click()
,并且正如您所期望的那样,您将在警报中获得“Hello World”。
您希望能够将“点击”功能用作事件处理程序:
$("button").on("click", object.click);
然而,您发现这不起作用,因为jQuery调用“click”函数,并将this
设置为单击按钮的DOM节点。这很烦人。由于JavaScript函数调用的语义,这也是不可避免的。
当您通过属性引用调用“click”函数时,语言会安排this
引用该对象。这就是object.click()
有效的原因。但是,当您获取对函数的引用并将其传递到函数边界时(如调用.on()
),该关系将丢失。 jQuery方法获取的所有内容都是一个简单的未经修饰的函数,它与其定义中涉及的原始对象完全没有内在联系。
因此,jQuery实际上只有两个选择。首先,它可以通过安排this
为undefined
来明确表明函数未连接的事实。然而,那不是很有用。另一种选择是为this
选择一些有趣的东西,这就是图书馆所做的事情。请注意,本机DOM级别0事件调度机制执行相同的操作。
答案 1 :(得分:2)
原因是jQuery想要模仿常规事件处理程序(没有jQuery或任何其他库创建的事件处理程序)如何工作。在常规事件处理程序中,this
的值指的是触发事件的DOM节点(如果有)。
实际上可以认为这是jQuery 不操纵内置行为的一个例子。