以下代码给了我一个未捕获的类型错误:非法调用:
document.querySelector("h1").addEventListener('click', function(evt) {
setTimeout(this.classList.add, 2000, "bold-h1");
});
但这有什么问题呢?会不会和我写的一样
document.querySelector("h1").addEventListener('click', function(evt) {
setTimeout(() => { this.classList.add("bold-h1"); }, 2000);
});
? (顺便说一下后者有效)
答案 0 :(得分:3)
setTimeout 调用的函数作为全局代码执行。 add 方法应该在 classList 对象上调用(即它的 this 将是一个 classList 对象) ,但在全局代码的情况下,它的 this 将是全局对象或在严格模式下未定义。
全局对象没有 classList 属性,所以 this.classList 返回 null,并调用任何方法(甚至试图访问 null 的任何属性都会引发错误。
第二种情况起作用的原因是作为侦听器传递的函数包装了箭头函数。箭头函数的 this 绑定到其封闭执行上下文的 this,因此箭头函数的 this 是 this > 侦听器,这是侦听器所在的元素。所以现在当匿名函数被 setTimeout 调用时,它的 this 是元素并且 this.classList.add(...)
起作用。