【普通函数、箭头函数、Vue中的this指向问题】

643 阅读3分钟

对于前端开发人员来说,搞清楚不同情况下的this指向,是一件非常头疼的事情。
经过收集资料,特此记录,以供后续复习使用

(1)普通函数中的this - 指向window
浏览器默认对象是window,如果一个函数体内,没有全局对象,则其中的this指向window

    var b = 1
    function fn(){
       let a = 2
       console.log(this.a)
       console.log(this.b)
    }
    fn()
    结果会输出 undefined 1
    因为let是块级作用域,所以生效区域只有在函数体内,而this指向的是window。所以会输出undefinedvar定义的变量是全局变量,所以可以正常输出。

(2)构造函数中的this - 指向new的对象

    function fn(){
        console.log(this)
    }
    const Fn = new fn()
    console.log(Fn)

    结果会输出:fn{}

(3)箭头函数 - 指向调用上下文
箭头函数中没有this,指向其所在的上下文。

    var a = 1  
    const Fn =(a,b)=>{
       console.log(this.a,b)
    }
    Fn(2,3) //监听函数指向上一层作用域

    结果会输出:1 3

(4)对象函数 - 指向这个对象

    const obj= {
         a:3,
         objFun:function () {
            console.log(this)
         }
        }
    obj.objFun()

    结果会输出:obj这个对象。

    当然,还有一种可能,如果对象函数是箭头函数得话,那this也会指向父级作用域,比如:
    var a = 1
    const obj= {
         a:3,
         objFun:()=>{
            console.log(this.a)
          }
      }
    obj.objFun()//对象函数

    结果会输出:1
    注意:对象中的函数应该和对象属于同级,所以父级作用域也相同。

(5)数组中有函数 - 指向这个数组

   function Fn() {
        console.log(this)
    }
    var arr = [2,3,Fn ,4]
    arr[2]() 
    
    结果会输出:这个数组

(6)window内置对象 - 指向window

 setTimeout(()=>{
        console.log(this)
  },1000)
 
 结果会输出window对象

(7)apply、call - 调用时指向第一个参数,没有传参时指向window

  var a = 1 //关键是这里是否定义
   function Fn() {
       console.log(this)
   }
  Fn.apply(this.a)
  如果a有定义,则this指向变为a。如果没有,则输出window

(8)Vue中的this指向问题

Vue中没有自定义new Vue的话默认this指向就是vueComponent。
官方的原话是:在Vue实例中,methods中如果用的是正常函数,那么它的this就指向Vue实例;
如果是箭头函数,this就指向window对象。

1、组件配置中:

data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是【VueComponent实例对象】

2、new Vue(options)配置中:

data函数、methods中的函数、watch中的函数、computed中的函数中,它们的this均是【Vue实例对象】。

一、Vue普通方法中的this:

指向直接调用者。
比如在mounted里使用thisthis指向调用它的Vue实例。
例如 obj.func ,那么func中的this就是obj,一般指的是实例。

二、vue所有生命周期中的钩子方法中的this:

比如在mounted里使用thisthis指向调用它的Vue实例。

三、Vue 中回调函数中的 this:

若回调函数为 匿名函数,非严格模式下指向 window,严格模式下为 undefined。
若回调函数为 自定义方法,则 this 指向 Vue 实例。
若回调函数为 箭头函数,则 this 指向 Vue 实例。

四、Vue 中 addEventListener 中的 this

通常,事件监听函数中的 this 都指向绑定事件的那个元素, 但是在 Vue 中,监听函数中的 this 也指向 Vue 实例。

五、在data里定义Object类型的变量时的this

在data里定义Object类型的变量时,会发现Object中访问不到vue的this属性,例如:
export default {
  data(){
    return {
      a: "123",
      b: {
        c: this.a
      }
    };
  },
  created() {
    console.log("b: ", this.b.c); // undefined
  }
}
想在b中访问this.a的数据,直接访问会返回undefined,因为这时c中的this指向的是b。
这种情况可以用到Object的get属性进行属性定义,例如:

export default {
  data(){
    return {
      a: "123",
      b: {
        _target: () => this,
        get target() {
          return this._target();
        },
 
        get c() {
          return this.target.a;
        },
      },
    };
  },
  created() {
    console.log("b: ", this.b.c); // 123
  }
}
此处将this映射到了Object变量内部,然后通过get的形式定义属性并获取,这样就解决问题啦。