javascript函数链接没有链成员了解彼此

时间:2011-08-31 22:22:03

标签: javascript coffeescript chain

我想创建一个像PowerShell,bash(|)或f#(|>)这样的javascript管道。 IE浏览器。相当于

的东西
getstuff() | sort() | grep("foo") | take(5)

我在coffeescript论坛上看到了对此的讨论,但最后他们搁置了它,因为每个人都说你可以用功能链来做同样的事情。但据我所知,需要getstuff返回一些有排序方法的东西; sort方法必须返回具有grep方法的东西等。这是非常有限的,因为它要求所有潜在的管道成员事先知道彼此。我知道JavaScript中有一些非常聪明的技巧,我仍处于101级 - 所以这是可行的

getstuff().sort.().grep().take()

没有那个约束

4 个答案:

答案 0 :(得分:2)

  

这是可行的

getstuff().sort.().grep().take()
     

没有那个约束

没有


  

我喜欢简短的回答!你能建议任何类似的事情吗?

在较高的层次上,你可以做一些类似于jQuery在引擎盖下做的事情来允许链接。创建一个类似数组的包装器对象类型,它具有您希望能够调用的所有函数;除了明确传递的参数之外,每个连续的链式调用都可以在内部堆栈上运行。

不要继续击败死去的jQuery马,但了解我正在谈论的内容的最好方法之一就是开始挖掘jQuery core source code并弄清楚链接是如何工作的。

答案 1 :(得分:2)

定义一个对象以支持你想要的功能链接实际上非常简单:

getStuff = ->
  sort: ->
    # set @stuff...
    this
  grep: (str) ->
    # modify @stuff...
    this
  take: (num) ->
    @stuff[num]

这就是让getstuff().sort.().grep('foo').take(5)工作所需的一切。

答案 2 :(得分:0)

您可以进行这些调用,而无需担心具有适当方法的返回值,如下所示:

take(5, grep("foo", sort(getstuff())));

但是,这并没有解决每个函数需要传递对它有意义的数据的问题。即便是JavaScript也不是那么滑。您可以在图像上调用sort()(例如),但没有有意义的方法来生成结果。

答案 3 :(得分:0)

您可以通过返回一个具有所有必需方法的特殊对象来执行类似操作,但可以使用它来代替最终值。例如,您可以返回一个包含所有这些方法的Array实例。

var getstuff = function () {
    obj = Array.apply(this, arguments);
    obj.take = function (n) {
        return this[n];
    };
    obj.grep = function (regexp) {
        return getstuff.apply(this, Array.prototype.filter.apply(this, [function (item) {
            return item.toString().search(regexp) !== -1;
        }]));
    };
    obj.splice = function () {
        return getstuff.apply(this, Array.prototype.splice.apply(this, arguments));
    }
    return obj;
}

// shows [-8, 1]
console.log(getstuff(3, 1, 2, 'b', -8).sort().grep(/\d+/).splice(0, 2));
// shows 3
var stuff = getstuff(3, 1, 2, 'b', -8).grep(/\d+/);
console.log(stuff.sort()[stuff.length]);

请注意,上面的实现并不是特别快,但是它仍然保持全局Allay的原型干净,从而返回具有特殊方法的数组,因此它不会干扰其他代码。

你可以通过在Array.prototype上定义这些特殊方法来加快速度,但你应该小心......

或者,如果您的浏览器支持继承Array,那么您只需要一个超类和一个方便的构造函数getstuff()