如何在Ramda中访问构造函数'this'?

时间:2016-12-08 18:35:48

标签: javascript ecmascript-6 ramda.js

每当我尝试访问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)

2 个答案:

答案 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)
}

即。将功能分配给getContentgetParents