js中this指向的常用判断方式

113 阅读1分钟

第一类:函数调用有.的调用情况,统一指向.前的对象

1, this->.前的对象

const obj={
    name:'xhh',
    fun:function(){
    console.log(`姓名是:${this.name}`)
}
obj.fun()   // 姓名是xhh

2,new 构造函数 this->new创建的新对象

  const age = 12
  function Obj (name, age) {
    this.name = name
    this.age = age
    this.fun = function () {
      console.log(this.age)
    }
  }
  new Obj('xhh', 16).fun() // 16

3, 构造函数.prototype.fun=function(){}, 因为原型对象上的方法未来都是‘子对象.fun()’的方式调用, 所以this->将来调用fun()的.前的对象

  function Obj (name, age) {
    this.nage = name
    this.age = age
  }
  Obj.prototype.fun = function (age) {
    this.age += age
    console.log(this.age)
  }
  const obj = new Obj('xhh', 12)
  obj.fun(10) //22

第二类:函数调用既没有.也没用new的情况,在非严格模式下, this->window,严格模式下, this->undefiled

1,直接fun()调用

注意:此处和文档中第一类第一点的this指向对比进行区分

  const name = 'zl'
  const obj = {
    name: 'xhh',
    age: 16,
    fun: function () {
      console.log(`姓名是${name}`)
    }
  }
  const fun = obj.fun
  fun()//zl  

2,匿名函数自调

  (function (i) {
    console.log(this)
  })(1) //window

3,回调函数

  setTimeout(function () {
    console.log(this)
  }, 0) //window

第三类,DOM事件处理函数,this->当前正在触发事件的.前的DOM对象

注意:此处的处理函数中的function不可以使用箭头函数,如果改为箭头函数, 则this指向了外层的window, 程序会报错

<div style="width: 500px;height: 500px;background-color: blueviolet;" id="button">点击</div>
  const button = document.getElementById('button')
  button.onclick = function () {
    console.log(this) // id为'button'的DOM元素
  }

第四类,箭头函数中的this,this->当前函数之外最近的作用域中的this

  function fun () {
    name = 'xhh'
    age = 16
    setTimeout(() => {
      console.log(this.name)
    }, 0)
  }
  fun() //xhh

其他:手动改变this指向,this绑定,apply,call,bind

  • apply:临时指定this指向,并执行函数一次,第二个参数是数组类型,最后将会展开并一次赋值给arguments
  • call:临时指定this指向,并执行函数一次,第二个参数以后依次会赋值给arguments
  • bind:生成函数副本, 永久绑定this指向
  • 箭头函数的底层原理就是bind绑定, 因此箭头函数无法再通过apply,call,bind改变this指向
    const person = {
    name: 'xhh',
    age: 12
  }
  const person2 = {
    name: 'zl',
    age: 16
  }
  function fun () {
    console.log(`姓名是:${this.name},年龄是:${this.age}`)
  }
  fun.call(person) //姓名是:xhh,年龄是:12
  fun.call(person2)//姓名是:zl,年龄是:16 
  const fun1 = fun.bind(person) 
  fun1() //姓名是:xhh,年龄是:12