addEventListener 回调中的 this 关键字

pld*_*ldg 9 javascript this addeventlistener

我阅读了有关此主题的其他一些答案,但我不确定我是否了解this关键字在addEventListener.

const button = document.querySelector('button');

function foo() { console.log(this) }

button.addEventListener('click', foo);
Run Code Online (Sandbox Code Playgroud)

foo是内部的常规函数addEventListener,它不是button对象上的方法。当foo被调用时应该在全局对象的上下文中执行,因此this应该等于window而不是button

看起来类似于这个例子的情况

const obj = {
  method: function (cb) {
    console.log('method', this); // `this` === `obj`

    return cb();
  }
};

obj.method(function() {
  console.log('cb', this); // `this` === `window`
});
Run Code Online (Sandbox Code Playgroud)

哪里obj可以算是buttonmethod可以是addEventListenercb回调里面的addEventListener

我知道我可以bind用来改变上下文,this但我想更深入地了解它为什么会这样工作。

为什么thisaddEventListener当前元素的上下文而不是全局对象上调用内部回调?

Moh*_*mpu 11

如果我们使用使用 function 关键字定义的函数作为事件处理程序,那么该事件处理程序函数将在绑定事件的元素的上下文中执行

button.addEventListener('click', foo);
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,thisfoo 中的值将是button元素。

如果我们使用箭头函数而不是它们,那么thisvalue 将是 window 对象

原因是this箭头函数与创建箭头函数的上下文具有相同的值

button.addEventListener('click', () => { console.log(this) // window } );
Run Code Online (Sandbox Code Playgroud)

更多关于词法 this 什么是词法“this”?


小智 3

虽然我们知道事件侦听器是在将“this”设置为事件目标的情况下执行的,但您找到的EventTarget链接中的 EventTarget.prototype.dispatchEvent 方法内的以下代码行将回答您有关其如何实现的问题。

for (var i = 0, l = stack.length; i < l; i++) {
    stack[i].call(this, event);
}
Run Code Online (Sandbox Code Playgroud)

“stack”数组具有回调函数,并且可以使用 .call 通过传入事件目标实例 (this) 和事件作为参数来调用它们。