ClojureScript 中的流畅界面

Fluent interface in ClojureScript

我正在用 ClojureScript 编写一个库,它将公开 public JavaScript API。由于它必须模仿现有 JavaScript 库的 API,因此我想展示同样流畅的 API :

myLib.prepareToDo()
     .something()
     .and('also')
     .somethingElse()
     .run(function(err, result) {
         console.log("yay!");
});

在 Javascript 中,可以创建一个流利的 API 像这样 site point):

var MyClass = function(a) {
    this.a = a;
}

MyClass.prototype.foo = function(b) {
    // Do some complex work   
    this.a += Math.cos(b);
    return this;
}

然后我可以这样称呼它:

var obj = new MyClass(5);
obj.foo(1).foo(2).foo(3);

现在,据我所知,ClojureScript 中没有 this 的概念,尽管显然可以访问它 this-as.

虽然我不知道如何使用它,因此我的问题。

如何在 ClojureScript 中创建流畅的界面?

(defrecord)this answer 来救援。将 "magic" 协议 Object 扩展到我们的记录或类型会导致定义的方法作为成员函数出现在 JavaScript 对象中。要启用 "fluent interface",某些方法 return MyClass.

的实例
(defrecord MyClass [a b]
    Object
      (something [this] this)
      (and-then [this s] (assoc this :a s))
      (something-else [this] (assoc this :b (str a "-" a)))
      (run [this f] (f a b)))

然后我们可以有一个像这样的 JavaScript 客户端:

var myClass = new my_namespace.core.MyClass();
myClass.something()
   .and_then("bar")
   .something_else()
   .run(function(a, b) { 
       console.log(a + " - " + b) });