一、this 关键字的作用
this 关键字引用了所在函数正在被调用时的对象。在不同的上下文中,this
的指向会发生变化。
this 指向全局对象(在浏览器中是 window
对象,在 Node.js 中是 global
对象)。
this 指向调用该函数的对象。如果该函数是通过对象的方法调用的,那么 this
指向该对象;如果是通过函数调用的,那么 this
指向全局对象。
this 继承自父级作用域中的 this
。
在类的构造函数中,使用 new
关键字调用类时,this
指向新创建的对象。
class MyClass {
constructor( {
this.value = 42;
}
}
let obj = new MyClass(;
console.log(obj.value; // 42
类的实例方法中的 this 默认指向实例本身,类方法中的 this 默认指向类本身。
class MyClass {
value = 42;
printValue( {
console.log(this.value;
}
static printValue( {
console.log(this.value;
}
}
let obj = new MyClass(;
obj.printValue(; // 42
MyClass.printValue(; // undefined
使用 Object.create
方法创建对象
使用 Object.create
方法创建是一种特殊的调用方式。在这种情况下,如果在对象的原型链上调用函数,则 this
指向该对象。
例如:
let baseObject = { value: 42 };
let obj = Object.create(baseObject;
function printValue( {
console.log(this.value;
}
printValue.call(obj; // 42
这种情况下,obj 的原型链上有 value 属性,所以调用 printValue( 方法时,this 指向 obj 对象。
在类中使用箭头函数
类中使用箭头函数定义的方法中的 this 指向是绑定的,它指向的是类的实例,而不是类本身。
例如:
class MyClass {
value = 42;
printValue = ( => {
console.log(this.value;
}
}
let obj = new MyClass(;
obj.printValue(; // 42
箭头函数的 this
是定义时的 this
,而不是调用时的 this
。因此,在类中使用箭头函数可以避免在方法中使用 bind
来绑定 this
。
在调用构造函数时,未使用 new 关键字
在这种情况下,this 指向全局对象。这种情况下不会创建新的对象,而是改变了全局对象的状态。
例如:
class MyClass {
constructor( {
this.value = 42;
}
}
let obj = MyClass(; // without new keyword
console.log(obj; // undefined
console.log(value; // 42
因此,在使用构造函数创建对象时,需要确保使用 new 关键字来调用构造函数,否则可能会导致意外的结果。
在使用构造函数时特别需要注意使用 new 关键字来调用。
在对象的方法中使用箭头函数会导致 this 指向问题
let obj = {
value: 42,
printValue: ( => {
console.log(this.value;
}
};
obj.printValue(; // undefined
这种情况下,在 obj 对象的 printValue 方法中使用了箭头函数,而箭头函数的 this 指向是定义时的 this,而不是调用时的 this。在这种情况下,因为箭头函数的 this 指向是定义时的 this,所以 this.value 指向的是 undefined,而不是 obj 对象中的 value。
例如:
let obj = {
value: 42,
printValue: function({
console.log(this.value;
}
};
obj.printValue(; // 42
或者
let obj = {
value: 42,
printValue: ( => {
console.log(obj.value;
}
};
obj.printValue(; // 42
在对象的方法中使用箭头函数会导致 this 指向问题,需要特别注意。可以使用箭头函数的父级作用域中的 this 或者普通函数来解决。
需要根据不同的场景来选择合适的方式来改变 this 的指向。
二、如何改变 this 上下文
call, apply
, bind
方法来改变 this
的上下文。
call 和 apply
方法允许您将函数的 this
指向指定的对象,并立即执行该函数。
call 方法的语法格式如下:
functionName.call(thisArg, arg1, arg2, ...;
apply
方法的语法格式如下:functionName.apply(thisArg, [arg1, arg2, ...];
bind
方法允许您将函数的this
指向指定的对象,但不立即执行函数,而是返回一个新函数,可以在将来执行。let newFunc = functionName.bind(thisArg, arg1, arg2, ...;
例如:
let obj = {value: 42}; function printValue( { console.log(this.value; } printValue.call(obj; // 42 printValue.apply(obj; // 42 let boundFunc = printValue.bind(obj; boundFunc(; // 42
总之,通过使用
call
,apply
,bind
方法,可以改变函数中的this
指向,从而在不同的上下文中使用同一个函数。