我正在经历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
,我不明白为什么。
没有"对"在这种情况下将函数绑定到元素的方法?
答案 0 :(得分:4)
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.
}