javascript函数链接,而链成员彼此不了解

javascript函数链接,而链成员彼此不了解,javascript,coffeescript,chain,Javascript,Coffeescript,Chain,我想创建一个javascript管道,如powershell、bash(|)或f(|>)。相当于 getstuff() | sort() | grep("foo") | take(5) 我在coffeescript论坛上看到了一个关于这个的讨论,但最后他们搁置了它,因为每个人都说你可以用函数链接做同样的事情。但就我所见,RequiredGetStuff返回的东西上有一个排序方法;sort方法必须返回包含grep方法的内容,等等。这是一个非常严格的限制,因为它要求所有潜在的管道成员事先相互了解。

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

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

getstuff().sort.().grep().take()
getstuff().sort.().grep().take()
没有这种约束

这可行吗

getstuff().sort.().grep().take()
getstuff().sort.().grep().take()
没有这种约束

没有



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

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

不是要一直打败jQuery这匹死马,但要理解我所说的,最好的方法之一就是开始挖掘并弄清楚链接是如何工作的

这可行吗

getstuff().sort.().grep().take()
getstuff().sort.().grep().take()
没有这种约束

没有



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

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


不是要一直打败jQuery这匹死马,但要理解我所说的,最好的方法之一就是开始挖掘并弄清楚链接是如何工作的

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

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

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

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

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

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

定义一个对象来支持您想要的函数链接类型实际上非常简单:

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

这就是你需要做的所有事情。
getstuff().sort.(.grep('foo')。做(5)
work.

定义一个对象来支持你想要的函数链接实际上非常简单:

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

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

你可以通过返回一个特殊的对象来做类似的事情,该对象上有所有必需的方法,但可以用来代替最终值。例如,您可以返回一个包含所有这些方法的
数组
实例

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
,那么您所需要的只是一个supclass和一个方便的构造函数,
getstuff()

您可以通过返回一个特殊对象来做类似的事情,该对象上有所有必需的方法,但可以用来代替最终值。例如,您可以返回一个包含所有这些方法的
数组
实例

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
上定义这些特殊方法来加快速度,但是您应该小心


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

我喜欢简短的答案!你能提出任何类似的建议吗?#coffeescript让我指向underline.js-这与使用#chain.js做同样的事情我喜欢简短的答案!你能提出任何类似的建议吗?#coffeescript让我指向underline.js-这与使用#.chainright做的事情是一样的,但我可以说管道的所有成员都必须期望接收字符串数组或某个特定类的实例,具体取决于最左边的管道成员。那么我的例子就有意义了。我知道我可以用“real”函数调用来实现,但这会失去它的灵活性,但我可以说管道的所有成员都必须期望接收,比如,字符串数组,或者某个特定类的实例,具体取决于最左边的管道成员。那么我的例子就有意义了。我知道我可以用“真正的”函数调用来实现它,但这会降低它的灵活性,但这需要getstuff知道它将与grep绑定。我希望能够提前链接彼此不了解的东西(比如bash进行head | grep |排序),但这需要getstuff知道它将与grep链接。我希望能够把不知道的事情联系起来