1. 什么是this?
在JavaScript中,this是一个特殊的关键字,它代表当前执行上下文中的对象。这里的“当前执行上下文”可以是一个函数、一个对象或者全局作用域。
2. this的四种常见情况
- 全局上下文
在全局作用域或者函数外部,this指向全局对象。在浏览器中,这个全局对象就是window。
console.log(this.document === document); // true
console.log(this === window); // true
this.a = 37;
console.log(window.a); // 37
-
函数上下文
在函数内部,this的值取决于函数是如何被调用的。- 简单调用
如果一个函数不是作为对象的方法被调用,那么this通常指向全局对象。
function f1(){ return this; } f1() === window; // 在浏览器中,非严格模式下为true- 作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象。
var o = { prop: 37, f: function() { return this.prop; } }; console.log(o.f()); // 37 - 简单调用
-
构造函数
当一个函数通过new关键字被用作构造函数时,this指向新创建的对象实例。
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); // 37
- 使用
.call()、.apply()、.bind()
这三个方法可以显式地指定函数执行时的this值。
function f(){
return this.a;
}
var o = {a: 37};
console.log(f.call(o)); // 37
console.log(f.apply(o)); // 37
console.log(f.bind(o)()); // 37
- 箭头函数中的
this
箭头函数是ES6引入的一个新特性,它在处理this时与普通函数有所不同。箭头函数没有自己的this绑定,它会捕获其所在上下文的this值。
// this绑定的是全局变量
let base_num = 100;
function opreate(a, b) {
let add = () => {
return this.base_num + a + b;
}
return add();
}
console.log(opreate(1, 2)) ;
// this绑定的是info
let info = {
a: 1,
f: function() {
let innerFunc = () =>{
console.log(this.a);
}
innerFunc();
}
}
info.f();
- 类中的
this
ES6引入了类的概念,类中的this与构造函数中的this类似,指向类的实例。
class MyClass {
constructor() {
this.a = 1;
}
method() {
return this.a;
}
}
const instance = new MyClass();
console.log(instance.method()); // 1
- 回调函数中的
this
在回调函数中,this的值可能会发生变化,因为它取决于回调函数的调用方式。但是可以通过显示的bind或者隐式的绑定this对象。
var obj = {
a: 1,
b: function() {
setTimeout(function() { // 这边因为setTimeout是全局函数调用,没有绑定对象,所以这边的this就指向了全局变量
console.log(this.a); // undefined
}, 100);
}
};
obj.b();
// 隐式绑定,通过箭头函数捕获其所在上下文的`this`值来隐式绑定
var obj = {
a: 1,
b: function () {
setTimeout(() => {
// 这边因为setTimeout是全局函数调用,没有绑定对象,所以这边的this就指向了全局变量
console.log(this.a); // 1
}, 100);
},
};
obj.b();
// 显示绑定
var obj = {
a: 1,
b: function () {
setTimeout(
function () {
// 这边因为setTimeout是全局函数调用,没有绑定对象,所以这边的this就指向了全局变量
console.log(this.a); // 1
}.bind(obj),
100
);
},
};
obj.b();