[JS核心知识点] this指向问题

183 阅读2分钟

this指向谁?

1, 普通函数指向函数的调用者:有个简便的方法就是看函数前面有没有点,如果有点,那么就指向点前面的那个值;

2, 箭头函数指向函数所在的所用域: 注意理解作用域,只有函数的{}构成作用域,对象的{}以及 if(){}都不构成作用域;

this永远指向最终调用的函数所在的对象

① this指向的,永远只可能是对象!

② this指向谁,永远不取决于this写在哪!而是取决于函数在哪调用。

③ this指向的对象,我们称之为函数的上下文context,也叫函数的调用者。

1. 当直接调用函数时,this指向window

  function Obj () {
    console.log(this)
  }
  Obj() // window

2. 函数为对象属性时,this指向该对象

  function Obj () {
    console.log(this)
  } 
  let obj = {
    name: 'hello',
    where: Obj
  }
  obj.where() // {name: "hello", where: ƒ}

3. 构造函数中,this指向实例化对象

  function Obj () {
    console.log(this)
  }  
  let obj = new Obj() // Obj{}

4. 在setTimeout和setInterval,this永远指向window

  function Obj () {
    setTimeout(function () {
  	  console.log(this)
    }, 100)
  } 
  let obj = {
    name: 'hello',
    where: Obj
  }
  obj.where() // window

为何在setTimeout和setInterval中this永远指向window呢?下面专门了解一下

setTimeout和setInterval中this指向问题

由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined

  function Obj () {
    this.checkThis = function () {
      console.log(this)
    },
    this.checkThisLast = function () {
      setTimeout(function() {
        console.log(this)
      },100)
    }
  }
  let obj = new Obj()
  obj.checkThis() // Obj{}
  obj.checkThisLast() // window

如何解决setTimeout和setInterval中this的指向问题呢?

变量保存this

  function Obj () {
    let self = this, // this绑定给一个变量
    this.checkThis = function () {
      console.log(this)
    },
    this.checkThisLast = function () {
      setTimeout(function() {
        console.log(self)
      },100)
    }
  }
  let obj = new Obj()
  obj.checkThis() // Obj{}
  obj.checkThisLast() // Obj{}

箭头函数

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this

  • 指向定义时所在的作用域,而不是指向运行时所在的作用域。
  function Obj () {
    this.checkThis = function () {
      console.log(this)
    },
    this.checkThisLast = function () {
      setTimeout(() => {
        console.log(this)
      },100)
    }
  }
  let obj = new Obj() 
  obj.checkThis() // obj{}
  obj.checkThisLast() // obj{}

bind()绑定

bind()用法是将函数绑定到对象上,会创建新的函数,函数体内的this值会被绑定到传入bind()的首个参数;f.bind(obj)相当于obj.f(),则f()的this指向obj

  • call(),apply()可以实现同样this绑定,但call()、apply()调用后立即执行,apply()需要接收数组参数
  function Obj () {
    this.checkThis = function () {
      console.log(this)
    },
    this.checkThisLast = function () {
      setTimeout(function () {
        console.log(this)
      }.bind(this),100)
    }
  }
  let obj = new Obj()
  obj.checkThis() // obj{}
  obj.checkThisLast() // obj{}