Vue中this的绑定

  之前写过一篇文章 ES6与React中this完全解惑 其实Vue也是相同的道理。在Vue的官方文档中提到:

  不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

  箭头函数里this是相同的道理,我更推荐MDN里对箭头函数this的说明“箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承 this

this.aaa = 3

new Vue({
  data: {
    a: 1
  },
  created: () => console.log(this)
})

  这段代码在浏览器执行后,输出的this是window对象。

  箭头函数中,this引用的是定义箭头函数的上下文。

  箭头函数中this,须通过查找作用域链来决定其值,箭头函数内部的this指向是固定的。如果箭头函数被非箭头函数包含,则this是最近一层非箭头函数的this;否则,this的值会被设置为全局对象。

      普通函数都有自己的this,Vue实例化被调用时都能正确指向组件实例。但箭头函数没有自己的this,它只能去找父级作用域中的this。这个父级作用域是谁呢?是组件实例吗?我们知道作用域只有两种:全局作用域和函数作用域(以及ES6里条件判断等新增的块级作用域)。回到我们写的vue代码,它本质就是一个对象(具体一点,是一个组件的配置对象,这个对象里面有data、mounted、methods等属性)也就是说,我们在一个对象里面去定义方法,因为对象不构成作用域,所以这些方法的父作用域都是全局作用域。箭头函数要去寻找this,就只能找到全局作用域中的this——window对象了。

 

 

        new Vue({
            el: '#app',
            data: {
                a: 3,
            },
            mounted: function () {
                (() => {
                    console.log(this.a)  // 打印3   该箭头函数的this指向mounted函数作用域里的this,mounted函数的this是经过Vue处理的为Vue实例。
                                       //  但若直接把mounted函数改成箭头函数就会出问题,会向外层找作用域里this,ES5模式下是window.
                })()
            }
        })

        class Clock extends Component {
            constructor(props) {
                this.state = {
                    time: 1
                }
            }
            componentDidMount() {
                this.setState({time: this.state.time + 1}, () => {
                    console.log(this.state.time)  //打印2   该箭头函数的this指向componentDidMount函数作用域里的this。
                })
            }
        }

 

posted @ 2019-01-25 10:28  姜瑞涛  阅读(4037)  评论(0编辑  收藏  举报