addEventListener、箭头函数和`this` [重复]
Posted
技术标签:
【中文标题】addEventListener、箭头函数和`this` [重复]【英文标题】:addEventListener, arrow functions, and `this` [duplicate] 【发布时间】:2017-06-14 08:27:27 【问题描述】:我正在经历 javascript30 挑战,在 lesson 3 中,他有一些事件监听器调用一个函数,该函数引用它作为 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
的解决方法:
const handleUpdate = (e) =>
const that = e.target;
const newValue = `$that.value$that.dataset.sizing || ''`;
etc.
但我首先尝试像这样绑定函数:
input.addEventListener('change', handleUpdate.bind(this));
但是函数内部的this
仍然指向window
,我不明白为什么。
在这种情况下是否没有“正确”的方式将函数绑定到元素?
【问题讨论】:
如果你想使用this
那么你需要使用常规函数。箭头函数不能真正与 this
一起正常工作。
另外,有没有正确的方法来使用箭头函数呢? 没有
我想我记得读过一些东西说或建议,明确编写箭头函数是为了避免影响“this”。
普通函数和this
或e.currentTarget
(不是e.target
!!)
箭头函数只允许从定义它们的环境继承'this'的值,而不是它们被调用的上下文。演示代码使用常规函数,'this'引用调用它的环境。根据定义,箭头函数不可能做到这一点,因此为什么不能在需要使用“this”的任何地方使用它们。
【参考方案1】:
这是什么?
this
是Javascript中的一个特殊关键字,指的是函数的执行环境:
this
将绑定到窗口
如果将函数传递给事件处理程序的回调,this
将绑定到引发事件的 DOM 元素
绑定
bind 方法基本上是说,当你调用函数时,用我的参数替换它。所以,例如:
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
的当前值的语法糖。例如,
let b = () => /* stuff */
和
一样let b = (function () /* stuff */).bind(this);
(基本上,我知道这是过于简单化了)
你的困境
在正常的事件过程中(不使用箭头函数),this
绑定到 DOM 元素。
当您执行创建事件处理程序input.addEventListener('change', handleUpdate.bind(this));
时,您正在全局范围内运行(所以this === window
)。所以你有效地运行input.addEventListener('change', handleUpdate.bind(window));
(这是你注意到的行为)。而使用箭头函数也是一样的。
如果你想用匿名函数替换回调,你应该这样做:
const handleUpdate = function (e)
const that = e.target;
const newValue = `$that.value$that.dataset.sizing || ''`;
// etc.
【讨论】:
箭头函数没有this
的概念。 this
在箭头函数内部是 this
在其包含的词法环境中的任何内容。
因此“我知道这是过于简单化了”。我认为当有人刚刚学习 JS 时尝试讨论词汇范围可能不是最好的教学方法。如果您正在阅读本文并想要更正确的解释:箭头函数不绑定 this
所以 this
只是指它在封闭词法范围中引用的任何内容。但是,如果他们刚刚将其绑定到封闭范围,这在功能上是相同的。
关键是你的整个答案可以替换为“箭头函数没有这个概念。箭头函数内部的 this 是它们包含的词法环境中的任何内容。不要使用箭头函数如果你需要绑定this
的值。"可能还有一些对 ECMAScript 2015 语言规范的引用。
这无法解释为什么他对 .bind 的尝试不起作用
这绝对可以解释为什么他的绑定尝试不起作用“箭头函数没有 this 的概念。箭头函数内部的 this 是它们包含的词法环境中的 this 。不要如果需要绑定 this 的值,请使用箭头函数。"以上是关于addEventListener、箭头函数和`this` [重复]的主要内容,如果未能解决你的问题,请参考以下文章