this指向-2023_05_07

class MyClass {
  constructor() {
    this.value = "Class value";
  }
​
  regularFunction() {
    console.log("Regular function: ", this.value);
  }
​
  arrowFunction = () => {
    console.log("Arrow function: ", this.value);
  }
}
​
const obj = {
  value: "Object value",
  method: function (callback) {
    callback();
  }
};
​
const instance = new MyClass();
​
// 问题1:请预测以下四个console.log语句的输出。
instance.regularFunction();
instance.arrowFunction();
obj.method(instance.regularFunction);
obj.method(instance.arrowFunction);
​
// 问题2:请解释为什么每个输出是这样的,并解释this的指向。// 问题3:现在假设我们有一个异步操作如下:
setTimeout(instance.regularFunction, 1000);
// 请解释这段代码中的this指向,以及为什么是这样的指向。如果需要保持this指向实例,应该如何修改代码?

这道题目包含以下几个要点:

  1. 类中的普通方法与箭头函数的this指向差异。
  2. 函数作为参数传递时this指向的变化。
  3. 异步函数如setTimeoutthis指向的问题。

答案

// 问题1:请预测以下四个console.log语句的输出。
instance.regularFunction(); // 输出:"Regular function: Class value"
instance.arrowFunction(); // 输出:"Arrow function: Class value"
obj.method(instance.regularFunction); // 输出:"Regular function: Object value"
obj.method(instance.arrowFunction); // 输出:"Arrow function: Class value"

问题2:请解释为什么每个输出是这样的,并解释this的指向。

  1. instance.regularFunction():在这个调用中,this指向实例instance,因为regularFunction是作为instance的一个方法被调用的。所以,输出的值是"Regular function: Class value"
  2. instance.arrowFunction():箭头函数不绑定自己的this,而是从创建时的上下文中继承this。在这个例子中,箭头函数是在MyClass的构造函数中创建的,因此this指向实例instance。所以,输出的值是"Arrow function: Class value"
  3. obj.method(instance.regularFunction):当instance.regularFunction作为回调函数传递给obj.method时,this的指向在调用时决定,即this将指向obj。所以,输出的值是"Regular function: Object value"
  4. obj.method(instance.arrowFunction):由于箭头函数继承了创建时的this值(即instance),无论如何调用它,this都将保持指向instance。所以,输出的值是"Arrow function: Class value"

问题3:现在假设我们有一个异步操作如下:

setTimeout(instance.regularFunction, 1000);

请解释这段代码中的this指向,以及为什么是这样的指向。

在这个例子中,当instance.regularFunction作为回调函数传递给setTimeout时,它会在全局上下文(浏览器中为window,Node.js中为global)中执行。因此,this将指向全局对象。如果strict mode没有启用,输出的值是"Regular function: undefined"。在strict mode下,thisundefined,将导致抛出错误。

如果需要保持this指向实例,可以通过以下几种方法之一来修改代码:

  1. 使用bind方法将this绑定到实例:
setTimeout(instance.regularFunction.bind(instance), 1000);
  1. 使用箭头函数作为回调函数,并在其中调用instance.regularFunction()
setTimeout(() => instance.regularFunction(), 1000);

这样修改后,setTimeout中的this将始终指向instance,并输出"Regular function: Class value"

原文链接:https://juejin.cn/post/7232234470779093049 作者:2002XiaoYu

(0)
上一篇 2023年5月13日 上午10:36
下一篇 2023年5月13日 上午10:46

相关推荐

发表回复

登录后才能评论