sách gpt4 ăn đã đi

javascript - 如何使用 _.reduce(和 _.each)从 Underscore.js 重写 _.every/_.all

In lại 作者:搜寻专家 更新时间:2023-11-01 04:16:52 30 4
mua khóa gpt4 giày nike

我正在为许多标准的 Underscore.js 函数重写底层代码,以提高我的 JavaScript 技能,但我有点受困于 _.every/ _.全部。似乎在库本身中,_.every/_.all 函数仅使用现有的 _.each 函数编写,但是我被鼓励使用我的 _.reduce 版本编写一个版本(它已经合并了我的 _.each 版本)。我在下面提供了这两个函数的代码。

第一个测试我的 _.every 函数(也见下文)失败是一个使用 _.identity 函数传递所有错误值的测试(只需返回作为参数输入的值)作为迭代器:

Bài kiểm tra:

  it('fails for a collection of all-falsy results', function() {
expect(_.every([null, 0, undefined], _.identity)).to.equal(false);
});

关于为什么我的 _.every 函数没有通过上面显示的测试以及其他多项测试(例如,混合真/假值、未定义值等),我有几个问题:

-调用iterator函数时,需要使用iterator.callvẫniterator.apply?如果是这样,我应该使用哪个以及如何指定参数?

-在这里使用 _.reduce thay vì _.each 有什么好处,特别是当 Underscore.js 库不使用 _ 时。减少?

-为什么return需要调用两次,一次是在调用_.reduce函数时,一次是在_.reduce中定义的匿名函数中(我'在构建使用 _.map 函数的函数时,您是否也想知道这一点)?对我来说,我似乎正在返回 _.reduce 函数的结果,它已经返回了一些东西。

_.每:

  _.every = function(collection, iterator) {
// TIP: Try re-using reduce() here.
return _.reduce(collection, function(allFound, item) {
return iterator(item) && allFound;
}, ĐÚNG VẬY);
};

_.每个:

_.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
khác {
for(var key in collection) {
iterator(collection[key], key, collection);
}
}
};

_.减少:

  _.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;
};

câu trả lời hay nhất

您的测试未通过,因为它没有按预期返回 SAI(尽管它返回的是错误值)。

_.every = function(collection, iterator) {
return _.reduce(collection, function(allFound, item) {
return iterator(item) && allFound;
}, ĐÚNG VẬY);
};

当您返回 iterator(item) && allFound 时发生的事情是,如果 iterator(item) 是假的(但不是 SAI),它不会返回SAI,而是返回iterator(item)的值。要自己验证这一点,请打开一个 REPL,然后键入 undefined && true;结果将是 không xác định,而不是 SAI

因此,如果您希望它显式返回 SAI,而不仅仅是一个假值,您必须将其强制转换为 bool 值。您可以执行 Boolean(truthy_or_falsey_value) hoặc !!truthy_or_falsey_value。我通常更喜欢后者,因此请更改您的实现:

_.every = function(collection, iterator) {
return _.reduce(collection, function(allFound, item) {
return !!iterator(item) && allFound;
}, ĐÚNG VẬY);
};

您的其他问题:

When calling the iterator function, do I need to use iterator.call or iterator.apply? If so, which do I use and how do I specify arguments?

这取决于你的目标是什么。 gọi áp dụng 主要用于控制函数体中 cái này 关键字的值。一些 JavaScript 的内置数组方法(如 Array.prototype.mapArray.prototype.filter)接受一个 thisArg,这就是提供使用 gọi hoặc áp dụng 执行回调。至于 gọi áp dụng 之间的区别,只是参数的处理方式不同。参见 câu trả lời này了解更多详情。

What benefit is there to using giảm bớt here rather than just mỗi, especially when the Underscore.js library does not use giảm bớt?

可能没有,或者很少。可能存在性能差异,但最好的找出方法是分析这两种方法。

Why does return need to be called twice, once when calling the _.reduce function, and once within the anonymous function defined within _.reduce

如果您想要一个函数——任何函数——返回一个值,您必须从该函数内部调用 return。您不能期望从内部函数调用 trở lại,并期望封闭函数神奇地理解它应该反过来返回被调用函数的值。如果未显式调用 trở lại,某些语言默认返回函数中最后一个表达式的值,这要么方便,要么令人困惑,具体取决于您的观点。如果您有使用过这种语言(例如 Ruby)的经验,那么所有的 trở lại 语句对您来说可能有点过分。

作为编者注,我觉得 trình lặp lại 是测试函数的一个糟糕的命名选择。它实际上并没有迭代任何东西(它作为参数的函数正在做任何迭代)。更好的名称可能是非常通用的 gọi lại hoặc cb。术语"predicate"表示将值映射到 ĐÚNG VẬY hoặc SAI 的函数,这是我的首选术语。另一个常见的选择是简单地 Bài kiểm tra,因为毕竟它只是一个对其参数执行二元过滤的函数。

关于javascript - 如何使用 _.reduce(和 _.each)从 Underscore.js 重写 _.every/_.all,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24298493/

30 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress