Skip to content

this 关键字

什么是 this 关键字

JavaScript 中的this关键字代表当前函数的执行上下文。

this的值依赖于函数的调用方式,它不是静态绑定而是动态绑定的,因此this的值在函数调用时才能确定。

this 的不同场景

全局上下文

在全局执行上下文中(不在任何函数内),this指向全局对象。

在浏览器中,全局对象是window对象;在 Node.js 中,全局对象是global对象。

WARNING

只有在非严格模式下,全局上下文中的this才指向全局对象;在严格模式下,全局上下文中的thisundefined

函数上下文

在函数上下文中,this的值取决于函数的调用方式。

普通函数调用

在非严格模式下,普通函数调用时,this指向全局对象;在严格模式下,thisundefined

js
function show() {
  console.log(this);
}
show();

方法调用

在对象方法中,this指向调用方法的对象。

js
var obj = {
  name: "Tom",
  show: function () {
    console.log(this.name);
  },
};
obj.show(); // 输出 'Tom'

构造函数调用

在构造函数中,this指向新创建的对象。

js
function Person(name) {
  this.name = name;
}
var person = new Person("Alice");
console.log(person.name); // 输出 'Alice'

箭头函数

箭头函数不绑定自己的this,无论它如何被调用,它都会捕获所在上下文的this值作为自己的this值。

js
const obj = {
  name: "Tom",
  show: () => {
    console.log(this.name);
  },
};

obj.show(); // 在浏览器中输出 undefined,因为箭头函数内部的 this 指向全局对象

通过callapplybind显示设置this

通过 call、apply 和 bind 方法,可以改变函数的执行上下文。

定义 Person 类用于演示 call、apply 和 bind 方法:

ts
class Person {
  name = "Anonymous";
  showDetails(age: number, interest: string) {
    return `${this.name} is ${age} years old and interested in ${interest}.`;
  }
}

call

call 第一个参数指定函数的执行上下文(this),剩余的参数是函数的参数。

call 方法会立即调用函数,且只临时改变函数的执行上下文。

ts
const alice = { name: "Alice" };

const resOfCall = Person.prototype.showDetails.call(alice, 25, "JavaScript");
console.log(resOfCall); // Alice is 25 years old and interested in JavaScript.

apply

apply 方法第一个参数指定函数的执行上下文(this),第二个参数是一个数组,数组中的元素是函数的参数。

apply 方法会立即调用函数,且只临时改变函数的执行上下文。

ts
const tom = { name: "Tom" };

const resOfApply = Person.prototype.showDetails.apply(tom, [18, "Java"]);
console.log(resOfApply); // Tom is 18 years old and interested in Java.

bind

bind 方法接收一个参数,即函数的执行上下文(this),返回一个新函数。

bind 方法不会立即调用函数,而是返回一个永久改变函数的执行上下文的新函数,可以在稍后调用。

ts
const bob = { name: "Bob" };

const showDetails = Person.prototype.showDetails.bind(bob);

const resOfBind = showDetails(30, "TypeScript");
console.log(resOfBind); // Bob is 30 years old and interested in TypeScript.

call、apply 和 bind 的区别

  • callapply 方法会立即调用函数,而 bind 方法会返回一个新函数,可以在稍后调用。
  • callapply 方法的区别在于参数的传递方式,call 方法的参数是逐个传递的,apply 方法的参数是数组传递的。