this 的绑定规则,你真的会吗?
2023-10-19 00:21:46
前言
作为一名 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 开发人员。