addEventListener、箭头函数和 `this` [英] addEventListener, arrow functions, and `this`

查看:102
本文介绍了addEventListener、箭头函数和 `this`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在接受 JavaScript30 挑战,在 第 3 课 他有一些事件侦听器调用一个函数,该函数引用它作为 this 调用的元素:

I'm going through the JavaScript30 challenge, and in lesson 3 he's got some event listener calling a function that references the element it's called on as this:

const inputs = document.querySelectorAll('.controls input');
function handleUpdate() {
  const suffix = this.dataset.sizing || '';
  document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
}
inputs.forEach(input => input.addEventListener('change', handleUpdate));
inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));

我正在尝试用 ES6 箭头函数重写它,但我无法让 this 正常工作.我有一个使用 target 的解决方法:

I'm trying to rewrite it with ES6 arrow function, but I can't get the this to work right. I got a workaround using target:

const handleUpdate = (e) => {
  const that = e.target;
  const newValue = `${that.value}${that.dataset.sizing || ''}`;
  etc.
}

但我首先尝试像这样绑定函数:

but I first tried to bind the function like that:

input.addEventListener('change', handleUpdate.bind(this));

但是函数内部的this仍然指向window,我不明白为什么.

But this inside the function still points to window and I don't understand why.

在这种情况下,是否没有正确"的方法将函数绑定到元素?

Is there no "right" way to bind the function to the element in this case?

推荐答案

这是什么?

this 是Javascript中的一个特殊关键字,指的是函数的执行环境:

What is this?

this is a special keyword in Javascript that refers to the executing environment of the function:

  • 如果你在全局范围内执行一个函数,this 将绑定到窗口
  • 如果您将函数传递给事件处理程序的回调,this 将绑定到引发事件的 DOM 元素
  • If you execute a function in the global scope, this will be bound to the window
  • If you pass the function to a callback for an event handler, this will be bound to the DOM element that raised the event

bind 方法基本上是说,当你调用函数时,用我的参数替换它.因此,例如:

The bind method basically says, when you call the function, replace this with whatever my argument is. So, for example:

let a = {}
function test_this() {
     return this === a;
}  

test_this(); // false
test_this.bind(a)(); // true (.bind() returns the bound function so we need to call the bound function to see the result)

此外,箭头函数只是将函数的this 绑定到this 的当前值的简单语法糖.例如,

Additionally arrow functions are simply syntactic sugar for binding the function's this to the current value of this. For example,

let b = () => { /* stuff */ }

let b = (function () { /* stuff */}).bind(this);

(基本上,我知道这过于简单化)

在正常的事件过程中(不使用箭头函数),this 绑定到 DOM 元素.

In the normal course of events (not using arrow functions), this is bound to the DOM element.

当您执行创建事件处理程序时 input.addEventListener('change', handleUpdate.bind(this)); 您在全局范围内运行(所以 这个 === 窗口).所以你有效地运行 input.addEventListener('change', handleUpdate.bind(window)); (这是你注意到的行为).使用箭头函数也是一回事.

When you're executing the creation of the event handler input.addEventListener('change', handleUpdate.bind(this)); you're running in the global scope (so this === window). So you're effectively running input.addEventListener('change', handleUpdate.bind(window)); (which is the behavior you're noticing). And using the arrow function is the same thing.

如果你想用匿名函数替换回调,你应该这样做:

If you want to replace the callback with an anonymous function you should instead do:

const handleUpdate = function (e) {
  const that = e.target;
  const newValue = `${that.value}${that.dataset.sizing || ''}`;
  // etc.
}

这篇关于addEventListener、箭头函数和 `this`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆