面试官:vue中watch的属性用箭头函数定义结果会怎么样


答:this是undefined,要更改的属性会报TypeError错误, Cannot read property 'xxx' of undefined。

因为箭头函数默绑定父级作用域的上下文,所以不会绑定vue实例,所以 this 是undefind。

不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

下面从源码角度分析一下:

我们配置的watch选项,所写的处理函数会创建watcher实例,把处理函数挂载给watcher,方法名叫cb。

下面这个run方法是watcher的原型方法,被观测的目标发生变化时,即你watch的属性变化时,它会通知它的dep中所有的watcher,执行update,然后立即执行下面这个run,重新计算你watch的属性的值,再次进行依赖收集,如果求出的新值和旧值不一样了,那么会执行cb,如下所示

run() { 
    if (!this.active) return 
    var value = this.get(); 
    if (value !== this.value || isObject(value) || this.deep) {
      var oldValue = this.value;  // oldValue保存旧值
      this.value = value;            // this.value更新为新值
      if (this.user) { 
        // 如果当前watcher是开发者定义的,即通过watch选项或$watch创建的watcher的cb是开发者编写的
        // 则行为不可预知,所以执行cb回调时try...catch一下,发生错误能给开发者一个友好的提示
        try { // 开发者编写的回调接收到被观察目标的新值和旧值
          this.cb.call(this.vm, value, oldValue)
        } catch (e) {
          handleError(e, this.vm, `callback for watcher "${this.expression}"`)
        }
      } else { // 不是用户创建的watcher,即渲染函数的watcher或计算属性的watcher
        this.cb.call(this.vm, value, oldValue) // 直接执行回调
      }
    }
  };

那么问题来了,如果cb不是箭头函数,那么它.call执行,执行时的this是能指定vm实例的

源码就是这么做,才把配置的函数中的this指向了vm实例

但如果是箭头函数,情况就不一样了,看下面例子。

function athis(){
    console.log(this === obj)
}
const bthis =()=>{
    console.log(this === obj)
}
athis.call(obj) // true
bthis.call(obj) // false

可见,你是无法将箭头函数执行中的this改绑定的,它只能从上级上下文去取this

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值