0

我想创建一个 javascript 管道,如 powershell、bash (|) 或 f# (|>)。IE。相当于

getstuff() | sort() | grep("foo") | take(5)

我在 coffeescript 论坛上看到了一个关于这个的讨论,但最后他们搁置了,因为每个人都说你可以用函数链做同样的事情。但据我所见, requires getstuff 返回具有排序方法的东西;sort 方法必须返回具有 grep 方法等的内容。这是非常严格的,因为它要求所有潜在的管道成员事先相互了解。我知道 JavaScript 有一些非常聪明的技巧,而且我仍然处于 101 级别 - 所以这是可行的

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

没有那个限制

4

4 回答 4

2

这是可行的吗

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

没有那个限制

不。


我喜欢简短的答案!你能建议任何可以做类似事情的方法吗

在高层次上,您可以做一些类似于 jQuery 在底层所做的事情以允许链接。创建一个类似数组的包装对象类型,它具有您希望能够调用的所有函数;除了显式传递的参数之外,每个连续的链式调用都可以在内部堆栈上进行操作。

不要继续击败死去的 jQuery 马,但理解我在说什么的最好方法之一就是开始挖掘jQuery 核心源代码并弄清楚链接是如何工作的。

于 2011-08-31T22:29:25.777 回答
2

定义一个对象来支持你想要的函数链实际上很容易:

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

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

于 2011-08-31T23:05:59.587 回答
0

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

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

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

于 2011-08-31T22:44:55.037 回答
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]);

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

您可以通过在 上定义这些特殊方法来使其更快Array.prototype,但您应该小心...

或者,如果您的浏览器支持子类Array化,那么您所需要的只是一个子类和一个方便的构造函数,getstuff().

于 2011-08-31T23:39:14.823 回答