每当我尝试访问Ramda Compose函数(this
)中的任何R.compose
时,我得到undefined
,也许是因为this
被绑定到了Ramda Compose函数
如何让this
访问Class
构造函数中启动的内容?
this.state
在以下代码中的getContent
内未定义:
export default class FaqStore {
constructor() {
this.state = new FaqState()
this.getParents()
}
getContent = R.concat(this.state.parents, R.prop('content'))
getParents = FaqService.getParents().then(this.getContent)
答案 0 :(得分:5)
Felix Kling的回答非常好。我想从Ramda添加一些更多的上下文。
Ramda(免责声明:我是其中一位作者)是关于函数式编程的。它尝试做两件事:使Javascript开发人员更容易转向更标准的FP实践,并使FP语言的用户更容易使用Javascript。完全没有强调与面向对象的编码风格的互操作。
有一次,Ramda确实尝试确保其某些功能确实维护this
上下文,这将允许它们用作OOP方法。但我们完全放弃了这个焦点;它一直是投机的,没有任何要求,当我们不小心打破它的某些功能时,我们根本就没有任何抱怨。似乎没有什么理由。同时,它使我们的实施变得复杂并且伤害了性能。因此,当我们发现需要重写功能时,我们不再试图确保维持这一功能。
这是有道理的。有些人认为Ramda是Underscore或lodash的替代品,但这似乎总是向我们倾斜。这些库引入了一些FP概念,但它们被设计为在多范式环境中工作,同样满足于命令式,OOP或FP代码库。 Ramda与众不同,旨在仅在功能系统中运行良好。它完全围绕构建系统的概念构建,通过组合纯函数。
由于这些原因,除了Felix所说的一切之外,没有理由期望Ramda函数能够维持你的this
背景。
答案 1 :(得分:3)
您似乎正在使用公共类字段提案。以这种方式创建的属性是evaluated before the constructor itself is executed(步骤8和11)。
即。你的代码相当于
export default class FaqStore {
constructor() {
this.getContent = R.concat(this.state.parents, R.prop('content'))
this.getParents = FaqService.getParents().then(this.getContent)
this.state = new FaqState()
this.getParents()
}
}
这清楚地表明您在初始化之前尝试访问this.state
。
可能的解决方案
不要使用提案并直接在构造函数中设置属性,初始化this.state
后:
export default class FaqStore {
constructor() {
this.state = new FaqState()
this.getContent = R.concat(this.state.parents, R.prop('content'))
this.getParents = FaqService.getParents().then(this.getContent)
this.getParents()
}
}
但是,仍然存在一个问题:分配给getParents
的值是一个承诺。您无法调用承诺(this.getParents()
)。也许你真正想要的是为getParents
分配一个函数:
this.getParents = () => FaqService.getParents().then(this.getContent)
也许R.concat
也不会返回函数,在这种情况下,this.getContent
也无法调用。在这种情况下,你真正想要的是
export default class FaqStore {
constructor() {
this.state = new FaqState()
this.getParents()
}
getContent = () => R.concat(this.state.parents, R.prop('content'))
getParents = () => FaqService.getParents().then(this.getContent)
}
即。将功能分配给getContent
和getParents
。