在您的示例中,onclick
处理程序非常简单:DOM 元素是一个对象,您将onclick
属性定义为一个函数。该函数有效地成为该 DOMElement/对象的方法。
单击该对象时,该函数将作为该元素的方法调用,因此 this 指向其所有者,即该元素。
简而言之,函数执行的上下文与创建的上下文相同(再次:在您的示例中作为 DOM 元素的方法),除非对函数对象的引用分配给另一个对象,或者当使用or & co在另一个上下文中调用该函数对象时。当然,还有比这更多的东西:正如我在上面所暗示的,函数本身就是对象,据说与它们的“所有者”松散耦合。好吧,实际上他们没有这样的所有者,每次调用函数时,都会确定其上下文:call
apply
var foo = someObject.someFunction;//reference to method
someObject.someFunction();//this === someObject, context is the object preceding the function
foo();//implies [window].foo(); ==> this is window, except for strict mode
正如@wroniasty 指出的那样,我谈论所有权可能有点令人困惑。问题是,函数是对象,它们不属于任何东西。当一个对象被分配一个方法时,该对象真正拥有的只是对给定函数对象的引用。当通过该引用调用该函数时,this
将指向拥有调用引用的对象。
当我们将其应用于您的elem.onclick = function(){}
时,我们看到该元素仅拥有对在某个范围内声明的函数表达式的引用(全局,命名空间对象,无关紧要)。当 click 事件触发时,该引用将用于调用处理程序,从而将对该元素的引用分配给this
. 澄清:
document.getElementById('foo').onclick = (function()
{//This function returns the actual handler
var that = this;//closure var
console.log(this);//logs window object
//defined in global context
return function(e)//actual handler
{
console.log(this === that);//false
console.log(this);//elem
console.log(that);//window
};
})();//IIFE
所以处理程序是在全局上下文中声明的,并且处理程序可以访问它在 using 中声明的上下文that
,这要归功于闭包(但这是另一回事)。onclick
关键是,事件使用元素的属性引用处理程序foo
。该属性是对函数对象的引用,因此函数对象将其上下文设置为进行调用的任何对象。
我确实希望这能消除我在函数所有权方面造成的任何混淆,以及 JS 中的上下文是如何确定的。