根据 Underscore.JS 来源 ( https://github.com/jashkenas/underscore/blob/master/underscore.js ):
// Start chaining a wrapped Underscore object.
chain: function() {
this._chain = true;
return this;
},
// Extracts the result from a wrapped and chained object.
value: function() {
return this._wrapped;
}
chain() 和 value() 函数只是 Underscore 对象的简单包装器。
所以如果我使用以下结构:
_.chain(someCollection)
.map(function1)
.map(function2)
.map(function3)
.value()
Underscore 将创建两个中间集合并执行三个枚举。
为什么 chain() 和 value() 方法没有像 LINQ 实现其方法那样实现为惰性求值?例如,这条链可以被视为:
_.chain(someCollection)
.map(function(x){
return function3(function2(function1(x)));
})
.value();
这种实现有没有JS相关的问题?
最佳答案
基本上,要按照您描述的方式使 .chain()
变得懒惰,每个方法都需要几乎两个版本。您将需要立即响应方法来执行文档所述的操作(返回一个数组),并且您将需要执行惰性评估的惰性方法(返回一个期望稍后为每个元素运行的函数)。
实现这一点的一种方法是将所有下划线写成惰性并将其公开为链式下划线。然后将普通下划线公开为惰性下划线的包装器,调用惰性下划线,立即求值,然后返回结果。有两个主要问题:(1)它需要更多的工作,(2)它是一个完全相反的架构,要求所有下划线都写成惰性的,只是为了支持链方法的惰性评估。
这当然是可行的,正如 JSLinq 和 .NET 的 LINQ 所展示的那样,但是在开发人员的开发和维护时间方面会付出巨大的代价,并且会增加复杂性和出现错误的可能性。 Underscore 在 1,200 行代码中提供了对 80 种不同实用方法的非惰性求值。 JSLinq 在 7,000 行代码中提供了 21 种不同实用方法的惰性求值。更多代码,更少功能。
有一个权衡。每个开发人员都可以做出自己的决定(只要他们为自己工作)。
关于javascript - 为什么 Underscore.js chain() 方法不是惰性的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17698697/