mobx 的 `action.bound` 和 class 函数上的箭头函数之间的区别?
Difference between mobx's `action.bound` and arrow functions on class functions?
在带有 babel 的 class 上使用箭头函数对其进行转换,因此定义绑定在构造函数中。因此它不在原型中,并且在继承时无法通过 super
获得。通过创建许多实例进行扩展时,它的效率也不高。
关于这个主题的博文很多,但我只是想知道在使用 babel 时 mobx.action.bound 与箭头函数的处理方式有何不同。
两者比较:
class Example {
test = () => {
console.log(this.message)
}
}
class Example {
@action.bound
test() {
console.log(this.message)
}
}
有 2 个变量 @action
和 @action.bound
影响:
- 绑定:
this
如何绑定到结果函数中。
- 原型:如果结果函数在原型中。
总而言之,规则如下:
@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
现在让我们尝试添加 @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
现在让我们尝试添加 @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
如您所见,@action
维护函数的绑定(或缺少绑定)。同时,@action.bound
将始终 return 绑定函数,从而将未绑定函数变为绑定函数,并且已绑定函数将保持绑定。
原型如何受到影响:
至于您对继承的担忧,这里是 Store
定义:
class Store {
unbound() {}
arrow = () => {}
@action unboundAction() {}
@action.bound unboundActionBound() {}
@action arrowAction = () => {}
@action.bound arrowActionBound = () => {}
}
这就是 storeInstance 的样子:
正如您所指出的,arrow = () => {}
不是原型的一部分。并回答你的问题, @action arrow = () => {}
不会产生原型中的函数。看起来 @action
保留了以前的行为。但是,@action.bound
将始终生成原型中的函数。
在带有 babel 的 class 上使用箭头函数对其进行转换,因此定义绑定在构造函数中。因此它不在原型中,并且在继承时无法通过 super
获得。通过创建许多实例进行扩展时,它的效率也不高。
关于这个主题的博文很多,但我只是想知道在使用 babel 时 mobx.action.bound 与箭头函数的处理方式有何不同。
两者比较:
class Example {
test = () => {
console.log(this.message)
}
}
class Example {
@action.bound
test() {
console.log(this.message)
}
}
有 2 个变量 @action
和 @action.bound
影响:
- 绑定:
this
如何绑定到结果函数中。 - 原型:如果结果函数在原型中。
总而言之,规则如下:
@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
现在让我们尝试添加 @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
现在让我们尝试添加 @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
如您所见,@action
维护函数的绑定(或缺少绑定)。同时,@action.bound
将始终 return 绑定函数,从而将未绑定函数变为绑定函数,并且已绑定函数将保持绑定。
原型如何受到影响:
至于您对继承的担忧,这里是 Store
定义:
class Store {
unbound() {}
arrow = () => {}
@action unboundAction() {}
@action.bound unboundActionBound() {}
@action arrowAction = () => {}
@action.bound arrowActionBound = () => {}
}
这就是 storeInstance 的样子:
正如您所指出的,arrow = () => {}
不是原型的一部分。并回答你的问题, @action arrow = () => {}
不会产生原型中的函数。看起来 @action
保留了以前的行为。但是,@action.bound
将始终生成原型中的函数。