讨论this的指向笔记

概念

this指的是当前执行上下文

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
理解了上面this的定义。下面几种常见的场景也就不难理解了。
this在严格模式下。和非严格模式下表现也不尽相同。

全局环境中的this

无论是否在严格模式下,this都指向全局对象window

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

普通函数中的this

非严格模式下。普通函数中的this指向全局对象,严格模式下this无指向。

  • 非严格模式下,直接调用test()其实等同于 window.test()
  • 严格模式下,test()本身没有对象调用。
    所以还是那个标准来判断 this始终指向调用它的对象
  function test(){
    return this;
  }
  // 非严格模式
  console.log(test() === window) // true

  // 严格模式
  console.log(test() === undefined) // true

箭头函数中的this

在箭头函数中,this永远指向与封闭词法环境的this保持一致。

  // 使用普通函数
  const test = {
    abc: function() {
      return function() {
        return this
      }
    }
  }
  let fn1 = obj.abc() // 等价于 function() { return this }
  // 若在严格模式则为undefined
  console.log(fn1() === window) // true

  // 使用箭头函数
  const test = {
    abc: function fnA() { // abc
      return () => this
    }
  }
  let fn1 = obj.abc() // 此时确定了封闭词法环境。为obj
  console.log(fn1() === window) // false
  console.log(fn1() === obj) // true

在上面的例子中,一个赋值给了test.abc的函数fnA,返回了另一个箭头函数。因此,在 fn1 调用时,箭头函数的this被永久设置为test.abc(fnA)的this(test)。当返回的函数(箭头函数)被调用时,它this始终是最初设置的test

对象中的方法中的this

在上面的例子中,已经有关于对象中的this的指向。

  • this一直指向调用该函数的对象。
const test = {
  nub: 520,
  f: function() {
    return this.nub;
  }
}

console.log(test.f()) // 520

class中的this

类内部总是严格模式。调用一个 this 值为 undefined 的方法会抛出错误。

  • 构造函数中
    this被绑定到正在构造的新对象
class Animal {
  constructor({ name }) {
    this.name = name
  }
}
const bird = new Animal({
  name: '鸟'
})
console.log(bird.name) // 鸟
  • 普通方法中
    和其他普通函数一样,方法中的 this 值取决于它们如何被调用。有时,改写这个行为,让类中的 this 值总是指向这个类实例会很有用
    为了做到这一点,可在构造函数中绑定类方法。
class People {
  constructor() {
    this.say = this.say.bind(this)
  }
  say() {}
}
  • 方法外部

call、apply、bind中的this

  • this将永久地被绑定到了bind的第一个参数
  • 在非严格模式下使用 call 和 apply 时,如果用作 this 的值不是对象,则会被尝试转换为对象。
posted @ 2021-12-16 17:32  skylei  阅读(34)  评论(0)    收藏  举报