FP:在没有实际状态变化的情况下反映状态?

时间:2013-04-12 19:40:03

标签: javascript functional-programming reactive-programming

我是一些高级函数式编程思想的新手,特别是:如何使用不可变数据。数据结构通常是复合材料,由较小的数据结构组成。例如,如果我们有一个家庭集合,它由一个家庭的所有成员组成。我们可以建造这个家庭:

var flintstones = new Family().
    add(new Member({name: 'Fred'})).    //returns new instance of family 
    add(new Member({name: 'Wilma'}).    // "
    add(new Member({name: 'Pebbles'})); // "
var fred = flintstones.get({name: 'Fred'}).set({lname: 'Flintstone'});
flintstones = fred.family(); //new instance of family with latest fred.

请注意,更改fred并未实际更改flintstones。我可以获得flintstones的新参考,但出于什么目的?由于所有对象都只是快照,我无法看到保留引用的重点。状态更改已被抽象出来,因此我们不会使用Observer模式。那么,关心状态变化的GUI等依赖性事物如何处理呢?保持事物同步的观察功能替代方案是什么?我没有看到对象本身在渲染自己时有任何业务。功能程序如何处理保持单页webapp GUI的状态同步?

值得Rich Hickey's talks启发我探索函数式编程。我得到了他的概念,但我很难实现实际的实现(在JavaScript中)。

1 个答案:

答案 0 :(得分:2)

在您的示例中,Family应该是不可变的。因此,对add的每次调用都必须返回一个基于现有对象内容的全新对象(它们本身是不可变的,因此复制它们不是问题)加上新的东西。同样,您在set上调用的Fred必须返回基于Fred的全新家庭成员,但姓氏不同。 (因此Flintstones内的原始Fred根本没有改变。)

这种功能风格的优点是,一旦你有一个对象的引用,你知道它不会改变。如果它在构造时有效,则不必继续检查它是否仍然有效。任何你可以将对象从代码中传出而不必首先克隆它以保护内部副本不被更改。

如果你想了解更多关于函数式编程的知识,你可能最好尝试一种纯函数式语言,比如Haskell或F#;尝试在JavaScript中进行函数式编程可能会令人困惑。