mobx的`action.bound`和类函数的箭头函数之间的区别?

bit*_*ten 5 javascript ecmascript-6 babeljs mobx

在使用babel的类上使用箭头函数进行转换,以便在构造函数中绑定定义.因此它不在原型中,并且super在继承时不可用.通过创建许多实例进行缩放时,它也不那么有效.

关于这个主题有更多的博客文章,但我只是想知道在使用babel时,与箭头函数相比,mobx.action.bound的处理方式有何不同.

比较两者:

class Example {
   test = () => {
      console.log(this.message)
   }
}

class Example {
   @action.bound
   test() {
      console.log(this.message)
   }
}
Run Code Online (Sandbox Code Playgroud)

Cro*_*sby 8

有两个变量,@action并且@action.bound会影响:

  1. 绑定:如何this绑定到结果函数中。
  2. 原型:如果结果函数在原型中。

总结一下,这些是规则:

  • @action保留原始函数的绑定和原型包含。如果原始函数未绑定,则结果将不会,反之亦然。而且,如果原始功能不在原型中,则结果将不会,反之亦然。
  • @action.bound 总是会产生一个绑定的函数,该函数在原型中。

绑定如何受到影响:

您可以像这样轻松测试:

class Store {
  unbound() {
    console.log('unbound', this)
  }

  arrow = () => {
    console.log('arrow', this)
  }
}
const storeInstance = new Store()
const unbound = storeInstance.unbound
const arrow = storeInstance.arrow
unbound()
arrow()
// console displays:
// unbound undefined
// arrow Store
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试添加@action

class Store {
  @action
  unbound() {
    console.log('unbound', this)
  }

  @action
  arrow = () => {
    console.log('arrow', this)
  }
}
const storeInstance = new Store()
const unbound = storeInstance.unbound
const arrow = storeInstance.arrow
unbound()
arrow()
// console still displays:
// unbound undefined
// arrow Store
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试添加@action.bound

class Store {
  @action.bound
  unbound() {
    console.log('unbound', this)
  }

  @action.bound
  arrow = () => {
    console.log('arrow', this)
  }
}
const storeInstance = new Store()
const unbound = storeInstance.unbound
const arrow = storeInstance.arrow
unbound()
arrow()
// console now displays:
// unbound Store
// arrow Store
Run Code Online (Sandbox Code Playgroud)

如您所见,@action维护函数的绑定(或缺少绑定)。与此同时,@action.bound将始终返回一个绑定函数,从而将一个未绑定的函数转换为一个绑定的函数,一个已经绑定的函数将保持绑定状态。

原型如何受到影响:

关于您对继承的关注,这里是Store定义:

class Store {
  unbound() {}
  arrow = () => {}
  @action unboundAction() {}
  @action.bound unboundActionBound() {}
  @action arrowAction = () => {}      
  @action.bound arrowActionBound = () => {}
}
Run Code Online (Sandbox Code Playgroud)

这是storeInstance的样子: 在此处输入图片说明

正如您指出的那样,arrow = () => {}它不是原型的一部分。并回答您的问题,@action arrow = () => {}将不会产生原型中的功能。看起来像@action保留了以前的行为。但是,@action.bound将始终产生原型中的功能。