为什么 Lodash 包装器不适用于 forEach?
Why Lodash wrapper doesn't work with forEach?
我在更新链接的 lodash 操作时遇到了这个问题,我不明白为什么它会以不同的方式工作
我将范围缩小到在 lodash 包装器上链接一个 forEach
let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).forEach(el => {el.c = 3; return el;}).groupBy('a')
console.log(res)
https://jsbin.com/wahokezeja/edit?js,console
这将引发错误:
"TypeError: _(...).forEach(...).groupBy is not a function
然而,当与地图链接时它工作正常
let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).map(el => {el.c = 3; return el;}).groupBy('a').value()
console.log(res)
https://jsbin.com/mofusel/1/edit?js,console
它与 _(tab).forEach 返回一个数组而不是 lodash 包装器有关,但不明白为什么会这样。
lodash forEach 的行为并不完全像 JS forEach,但也不完全像 map。 _.map([1,2,3],a=>2*a)
将 return 数组 [2,4,6]
正如您所期望的那样,但是 _.forEach([1,2,3],a=>a*2)
returns [1,2,3]
。它旨在对每个数组元素执行一个操作(如 JS [].forEach
),但它不是 return 修改后的数组,而是 return 是 原始 数组是为了方便。如果要修改数组,请使用 map
.
尝试以下操作:
var arr=[1,2,3];
var rslt=_(arr).forEach(v=>v*2);
console.log(arr===rslt);
并且您可以看到它 return 是正确的 - 来自 forEach 的 'result',无论是否包装,都只是原始数组。
在深入研究了 lodash 代码和@VLAZ 的一些有用评论之后,理解这一点的关键是与链接相关的惰性求值(这是上面提到的数组包装点)。 (包装的)链式方法启用惰性评估。如果您调用 _(array).map(fn1).map(fn2).value()
,则在调用 value 方法之前不会进行评估。这是一个很好的效率改进,因为(在这种情况下)只生成一个输出数组(不像标准的 JS map 方法会导致在每一步之后生成中间数组)。然而 forEach
不同 - 它需要立即执行,因此它结束了链。
我在更新链接的 lodash 操作时遇到了这个问题,我不明白为什么它会以不同的方式工作
我将范围缩小到在 lodash 包装器上链接一个 forEach
let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).forEach(el => {el.c = 3; return el;}).groupBy('a')
console.log(res)
https://jsbin.com/wahokezeja/edit?js,console
这将引发错误:
"TypeError: _(...).forEach(...).groupBy is not a function
然而,当与地图链接时它工作正常
let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).map(el => {el.c = 3; return el;}).groupBy('a').value()
console.log(res)
https://jsbin.com/mofusel/1/edit?js,console
它与 _(tab).forEach 返回一个数组而不是 lodash 包装器有关,但不明白为什么会这样。
lodash forEach 的行为并不完全像 JS forEach,但也不完全像 map。 _.map([1,2,3],a=>2*a)
将 return 数组 [2,4,6]
正如您所期望的那样,但是 _.forEach([1,2,3],a=>a*2)
returns [1,2,3]
。它旨在对每个数组元素执行一个操作(如 JS [].forEach
),但它不是 return 修改后的数组,而是 return 是 原始 数组是为了方便。如果要修改数组,请使用 map
.
尝试以下操作:
var arr=[1,2,3];
var rslt=_(arr).forEach(v=>v*2);
console.log(arr===rslt);
并且您可以看到它 return 是正确的 - 来自 forEach 的 'result',无论是否包装,都只是原始数组。
在深入研究了 lodash 代码和@VLAZ 的一些有用评论之后,理解这一点的关键是与链接相关的惰性求值(这是上面提到的数组包装点)。 (包装的)链式方法启用惰性评估。如果您调用 _(array).map(fn1).map(fn2).value()
,则在调用 value 方法之前不会进行评估。这是一个很好的效率改进,因为(在这种情况下)只生成一个输出数组(不像标准的 JS map 方法会导致在每一步之后生成中间数组)。然而 forEach
不同 - 它需要立即执行,因此它结束了链。