Skip to content

this 指向怎么判断? ​

普通函数的 this 由调用方式决定,不由它写在哪决定。箭头函数没有自己的 this,用的是定义时外层函数的 this。

按这个顺序判断:

  1. new 调用:this 是新对象。
  2. call / apply / bind:this 是传入的对象。new 的优先级比 bind 高。
  3. 方法调用 obj.fn():this 是 obj。
  4. 直接调用 fn():严格模式是 undefined,否则是全局对象。
  5. 箭头函数不走上面的规则。

原理 ​

js
"use strict"
const obj = {
  name: "obj",
  regular() {
    return this.name
  },
  arrow: () => {
    return this
  }
}

obj.regular() // "obj"
const fn = obj.regular
fn() // 严格模式下 this 是 undefined,读 name 会抛错

把方法拆出来交给 setTimeout 或事件监听后,调用方不再是原对象,this 就变了。要保住它,可以用箭头函数包一层,或事先 bind。类字段箭头函数也能保住 this,但每个实例都会有一份函数,不在原型上共享。

嵌套的普通函数不会继承外层 this。同一位置写成箭头函数才会。

追问 ​

箭头函数能当构造函数吗?

不能。它没有 [[Construct]],也没有自己的 prototype,new 会抛错。

类字段箭头函数和原型方法怎么选?

回调要传给别人、又必须指向实例时,类字段箭头函数省事。希望子类共享、或要放在原型上覆盖,用原型方法,在传出去的地方再绑定。

bind 之后还能 new 吗?

可以。new 时忽略 bind 固定的 this,预先传入的参数仍然生效。见 手写 bind。

易错点 ​

  • obj.fn() 和 const f = obj.fn; f() 的 this 不同。
  • DOM 监听里,普通函数的 this 是当前元素;箭头函数的 this 是定义位置的外层,通常不是元素。
  • 严格模式不会把独立调用的 this 修成全局对象。

相关 ​