我正在努力將許多標準Underscore.js函數的底層代碼重寫爲工作在我的JavaScript技能上,有點卡住了_.every
/_.all
。看起來在庫本身中,_.every
/_.all
函數僅使用現有的_.each
函數編寫,但我被鼓勵使用我的版本_.reduce
(它已經合併我的版本_.each
)編寫一個版本。我在下面提供了這兩個函數的代碼。如何使用_.reduce(和_.each)重寫_ _very/_。all來自Underscore.js
第一個測試我_.every
功能(見下文也一樣)失敗是一個地方全是假的值在使用_.identity
函數傳遞(簡單地返回輸入爲參數值)作爲迭代器:
測試:
it('fails for a collection of all-falsy results', function() {
expect(_.every([null, 0, undefined], _.identity)).to.equal(false);
});
我有幾個問題,爲什麼我的_.every
功能失敗上面的測試,與多個其他測試一起(例如,混合真/假值,不確定值等):
- 調用迭代器函數時,是否需要使用iterator.call
或iterator.apply
?如果是這樣,我該怎麼使用以及如何指定參數?
- 在這裏使用_.reduce
而不僅僅是_.each
有什麼好處,特別是當Underscore.js庫不使用_.reduce
?
- 爲什麼不回需要被調用兩次,一次調用_.reduce
功能時,和內內_.reduce
定義的匿名函數一次(我還構建利用_.map
功能函數時不知道這一點)?對我來說,我似乎返回了_.reduce
函數的結果,該函數已經返回了一些東西。
_.every:
_.every = function(collection, iterator) {
// TIP: Try re-using reduce() here.
return _.reduce(collection, function(allFound, item) {
return iterator(item) && allFound;
}, true);
};
_.each:
_.each = function(collection, iterator) {
// define spec for arrays
if (Array.isArray(collection)) {
for(var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
}
// define spec for objects
else {
for(var key in collection) {
iterator(collection[key], key, collection);
}
}
};
_.reduce:
_.reduce = function(collection, iterator, accumulator) {
// add condition to set accumulator if no explicit starting value is given.
if (arguments.length < 3) {
accumulator = collection[0];
}
_.each(collection, function(value) {
accumulator = iterator(accumulator, value);
});
return accumulator;
};