Skip to content

理解JavaScript中的"this"关键字

什么是this

在JavaScript中,this关键字指的是当前执行代码的对象。this的简短版本如下所示:

  • 默认情况下,this指向全局对象。
  • 在函数中,当不在严格模式下时,this指向全局对象。
  • 在函数中,当在严格模式下时,thisundefined
  • 在箭头函数中,this保留了封闭词法上下文的this的值。
  • 在对象方法中,this指的是调用该方法的对象。
  • 在构造函数调用中,this绑定到正在构造的新对象。
  • 在事件处理程序中,this绑定到放置监听器的元素。

全局上下文

在全局执行上下文中,this指向全局对象。

console.log(this === window); // true

函数上下文

当不在严格模式下时,函数的this指向全局对象。

function f() {
  return this;
}

```js
console.log(f() === window); // true

在严格模式下,如果在进入执行上下文时没有设置函数的this,则this将为undefined

'use strict';

function f() {
  return this;
}

console.log(f()); // undefined

对象上下文

当一个函数作为对象的方法调用时,this指向调用该方法的对象。这适用于在对象的原型链上的任何位置定义的方法(即自身和继承的方法)。

const obj = {
  f: function() {
    return this;
  }
};

const myObj = Object.create(obj);
myObj.foo = 1;

console.log(myObj.f()); // { foo: 1 }

同样地,在构造函数内部使用时,this指的是正在构造的对象。

class C {
  constructor() {
    this.x = 10;
  }
}

const obj = new C();
console.log(obj.x); // 10

箭头函数的上下文

在箭头函数中,this保留了封闭词法上下文的值。

const f = () => this;

console.log(f() === window); // true

const obj = {
  foo: function() {
    const baz = () => this;
    return baz();
  },
  bar: () => this
};

console.log(obj.foo()); // { foo, bar }
console.log(obj.bar() === window); // true

请注意,在第二个示例中,箭头函数的this指的是全局对象,除非它被包装在一个常规的function调用中,其this指的是调用它的对象,并且其词法上下文由箭头函数保留。

事件处理程序上下文

在事件处理程序中使用时,this指的是监听器所放置的元素。

const el = document.getElementById('my-el');

el.addEventListener('click', function() {
  console.log(this === el); // true
});

绑定 this

使用 Function.prototype.bind() 可以从现有函数中返回一个新函数,其中 this 永久绑定到 bind() 的第一个参数。

function f() {
  return this.foo;
}

const x = f.bind({foo: 'hello'});
console.log(x()); // 'hello'

类似地,使用 Function.prototype.call()Function.prototype.apply() 将调用函数的 this 仅绑定到这两个函数的第一个参数,仅用于此次调用。

function f() {
  return this.foo;
}```

```javascript
console.log(f.call({foo: 'hi'})); // 'hi'
console.log(f.call({foo: 'hi'})); // 'hi'
console.log(f.call({foo: 'hi'})); // 'hi'