在 JavaScript 中,this 的指向问题一直是让开发者头疼的问题。this 的指向取决于函数的调用方式,主要有以下几种绑定规则:
1. 默认绑定
当函数独立调用时,this 默认指向全局对象(在浏览器中是 window,在 Node.js 中是 global)。
javascript
function foo() {
console.log(this.a);
}
var a = 2;
foo(); // 2在严格模式下,默认绑定会失效,this 会指向 undefined:
javascript
function foo() {
'use strict';
console.log(this.a);
}
var a = 2;
foo(); // TypeError: Cannot read property 'a' of undefined2. 隐式绑定
当函数作为对象的方法调用时,this 指向该对象。
javascript
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2需要注意的是,隐式绑定可能会丢失:
javascript
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函数别名
var a = '全局变量'; // 全局变量
bar(); // '全局变量'3. 显式绑定
通过 call()、apply() 或 bind() 方法,我们可以显式地指定 this 的指向。
javascript
function foo() {
console.log(this.a);
}
var obj = {
a: 2
};
foo.call(obj); // 2
foo.apply(obj); // 2
var bar = foo.bind(obj);
bar(); // 24. new 绑定
使用 new 关键字调用函数时,会创建一个新对象,并将 this 绑定到这个新对象上。
javascript
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log(bar.a); // 2绑定规则的优先级
这四种绑定规则的优先级从高到低是:
- new 绑定
- 显式绑定
- 隐式绑定
- 默认绑定
箭头函数中的 this
箭头函数不遵循上述规则,它的 this 继承自外层作用域:
javascript
function foo() {
setTimeout(() => {
console.log(this.a);
}, 100);
}
var obj = {
a: 2
};
foo.call(obj); // 2