返回

this 的绑定规则,你真的会吗?

前端

前言

作为一名 JavaScript 开发人员,你一定听说过 this 。this 关键字是 JavaScript 中的一个非常重要的概念,理解它的绑定规则对于编写出健壮可维护的代码至关重要。

关于 this 最多的说法,就是:“谁调用它,this 就指向谁。”这话呢,不能说它错了,只能说它讲得不够严谨。为什么呢?我们先来了解一下 this 的几种绑定规则。

this 的绑定规则

this 的绑定规则主要有四种:默认绑定、隐式绑定、显式绑定和箭头函数绑定。

默认绑定

默认绑定发生在全局环境下,或者说函数在没有被任何对象调用的时候。此时,this 指向全局对象,在浏览器环境下就是 window 对象,在 Node.js 环境下就是 global 对象。

隐式绑定

隐式绑定发生在对象的方法被调用的时候。此时,this 指向该对象。

显式绑定

显式绑定可以通过 call、apply 和 bind 方法来实现。通过这些方法,我们可以手动指定函数的 this 值。

箭头函数绑定

箭头函数的 this 值与它所在的词法作用域有关,而不是由函数的调用方式决定的。

this 的绑定规则详解

默认绑定

默认绑定是最简单的一种绑定规则。当函数在没有被任何对象调用的时候,this 指向全局对象。

function foo() {
  console.log(this);
}

foo(); // 输出:window

在浏览器环境下,window 对象就是全局对象,所以上面的代码会输出 window 对象。

隐式绑定

隐式绑定发生在对象的方法被调用的时候。此时,this 指向该对象。

const obj = {
  name: '张三',
  sayHello() {
    console.log(`Hello, ${this.name}!`);
  }
};

obj.sayHello(); // 输出:Hello, 张三!

在上面的代码中,sayHello 方法是对象 obj 的一个方法。当我们调用 obj.sayHello() 的时候,this 就指向对象 obj,所以代码会输出 "Hello, 张三!"。

显式绑定

显式绑定可以通过 call、apply 和 bind 方法来实现。通过这些方法,我们可以手动指定函数的 this 值。

const obj = {
  name: '张三'
};

function foo() {
  console.log(this.name);
}

foo.call(obj); // 输出:张三
foo.apply(obj); // 输出:张三
const boundFoo = foo.bind(obj);
boundFoo(); // 输出:张三

在上面的代码中,我们通过 call、apply 和 bind 方法将 foo 函数的 this 值显式地绑定到了对象 obj 上,所以代码会输出 "张三"。

箭头函数绑定

箭头函数的 this 值与它所在的词法作用域有关,而不是由函数的调用方式决定的。

const obj = {
  name: '张三',
  sayHello() {
    console.log(`Hello, ${this.name}!`);
  },
  sayHelloArrow: () => {
    console.log(`Hello, ${this.name}!`);
  }
};

obj.sayHello(); // 输出:Hello, 张三!
obj.sayHelloArrow(); // 输出:undefined

在上面的代码中,sayHello 方法是对象 obj 的一个普通方法,而 sayHelloArrow 方法是一个箭头函数。当我们调用 obj.sayHello() 的时候,this 指向对象 obj,所以代码会输出 "Hello, 张三!"。但是,当我们调用 obj.sayHelloArrow() 的时候,this 指向的是 undefined,所以代码会输出 "undefined"。

this 的绑定规则总结

  • 默认绑定:当函数在没有被任何对象调用的时候,this 指向全局对象。
  • 隐式绑定:当对象的方法被调用的时候,this 指向该对象。
  • 显式绑定:可以通过 call、apply 和 bind 方法来实现,手动指定函数的 this 值。
  • 箭头函数绑定:箭头函数的 this 值与它所在的词法作用域有关,而不是由函数的调用方式决定的。

结语

this 的绑定规则是 JavaScript 中一个非常重要的概念,理解它对于编写出健壮可维护的代码至关重要。通过学习这篇文章,你应该已经对 this 的绑定规则有了比较全面的了解。希望这些知识能够帮助你成为一名更加优秀的 JavaScript 开发人员。