简体   繁体   English

当我从 setTimeout 添加 class 时出现“未捕获的 TypeError:非法调用”

[英]“Uncaught TypeError: Illegal invocation” when I add a class from setTimeout

the following code gives me a Uncaught TypeError: Illegal invocation :以下代码给了我一个Uncaught TypeError: Illegal invocation

document.querySelector("h1").addEventListener('click', function(evt) {
  setTimeout(this.classList.add, 2000, "bold-h1");
});

But what's wrong with it?但它有什么问题呢? Wouldn't that be the same as if I would write那不就和我写的一样吗

document.querySelector("h1").addEventListener('click', function(evt) {
  setTimeout(() => { this.classList.add("bold-h1"); }, 2000);
});

? ? (the latter works by the way) (后者顺便说一句)

Functions invoked by setTimeout are executed as global code. setTimeout调用的函数作为全局代码执行。 The add method is expected to be called on a classList object (ie its this will be a classList object), but in the case of global code its this will be the global object or undefined in strict mode. add方法预计会在classList object 上调用(即,它的this将是一个classList对象),但在全局代码的情况下,它的this将是全局 object 或在严格模式下未定义。

The global object doesn't have a classList property so this.classList returns null , and calling any method (or even attempting to access any property) of null throws an error.全局 object 没有classList属性,因此this.classList返回null ,调用 null 的任何方法(甚至尝试访问任何属性)都会引发错误。

The reason that the second case works is that the function passed as the listener wraps the arrow function.第二种情况有效的原因是 function 在侦听器包装箭头 function 时传递。 An arrow function's this is bound to the this of its enclosing execution context, so the arrow function's this is the this of the listener, which is the element the listener is on.箭头函数的this绑定到其封闭的执行上下文的this ,所以箭头函数的this是监听器的this ,也就是监听器所在的元素。 So now when the anonymous function is called by setTimeout , its this is the element and this.classList.add(...) works.因此,现在当setTimeout调用匿名 function 时,它的this是元素并且this.classList.add(...)有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM