返回

this 的本质与 bind 的妙用

见解分享

相信学习过 JavaScript 的朋友都会有一个这样的烦恼,那就是this的指向问题,为什么有的时候需要 bind,有的时候又不适用呢?

下面我就通过几个简短的案例,来帮助大家捋一下。

1. 当指定一个事件执行函数的时候,class 里的 this 会变化

我们先来看一个最常见的场景,当我们给一个元素添加一个事件执行函数时,比如:

document.getElementById('btn').addEventListener('click', function() {
  console.log(this); // this 指向的是元素本身
});

在这种场景下,this 指向的是元素本身,这是没有争议的。

但当我们把这个事件执行函数换成一个类的方法时,比如:

class MyClass {
  constructor() {
    document.getElementById('btn').addEventListener('click', this.handleClick);
  }

  handleClick() {
    console.log(this); // this 指向的是 MyClass 的实例
  }
}

new MyClass();

这时,this 就指向了 MyClass 的实例。

2. 不想套一层方法就可以使用箭头函数

在箭头函数中,this 是继承外层作用域的 this 的,所以,如果你不想为某个元素添加一个事件执行函数时多套一层方法,就可以使用箭头函数,比如:

document.getElementById('btn').addEventListener('click', () => {
  console.log(this); // this 指向的是元素本身
});

3. 作用域和闭包

在 JavaScript 中,this 的指向还与作用域和闭包有很大关系。

作用域决定了 this 的指向,而闭包可以改变 this 的指向。

比如,我们来看这样的一个代码:

var name = 'John';

var func = function() {
  console.log(this.name); // this 指向的是 window 对象
};

func(); // "John"

var obj = {
  name: 'Mary',
  func: func
};

obj.func(); // "undefined"

在第一个函数中,this 指向的是 window 对象,这是因为 func 函数的作用域是 window 对象。

但在 obj.func() 中,this 却指向了 obj 对象,这是因为 obj.func() 是一个闭包,而闭包可以改变 this 的指向。

总结

从以上的几个案例中,我们可以看出,this 的指向是会变化的,这与以下因素有关:

  • 作用域
  • 闭包
  • 事件执行函数

在使用 JavaScript 的过程中,我们一定要注意 this 的指向,以避免出现一些不必要的错误。

希望这篇小文章能让你对 this 的本质与 bind 的妙用有所帮助。