# invokeMap
# Description
调用 path(路径)上的方法处理 collection(集合) 中的每个元素,返回一个数组,包含每次调用方法得到的结果。任何附加的参数提供给每个被调用的方法。如果 methodName(方法名)是一个函数,每次调用函数时,内部的 this 指向集合中的每个元素。
# Params
(collection, path, args)
# Return
Array
# Depend
import baseEach from './.internal/baseEach.js'
import invoke from './invoke.js'
import isArrayLike from './isArrayLike.js'
# Code
function invokeMap(collection, path, args) {
let index = -1
const isFunc = typeof path === 'function'
const result = isArrayLike(collection) ? new Array(collection.length) : []
baseEach(collection, (value) => {
result[++index] = isFunc ? path.apply(value, args) : invoke(value, path, args)
})
return result
}
# Analyze
判断了传入的
path
是否本身就是一个function
同时判断了 传入的
collection
是否为一个类数组,如果是类数组,则new
一个 等长的数组,否则 设置result
为 空数组使用
baseEach
进行遍历,进行了判断,如果传入的path
是一个函数,则直接使用path.apply
,这里绑定的this
是value
。否则使用invoke
拿到path
路径对应的函数,在执行在遍历完成后,返回
result
有一点需要注意,如果
path
是路径的话,那么forEach
遍历时,每次invoke
调用的其实是相对于collection
一级的属性路径const obj = { a: { b: { c: 1 } }, b: { c: { d: Object.prototype.toString } }, c: 1 }
假设传入的是
c.d
, 其实每次调用就相当于调用了obj.a.c.d
obj.b.c.d
...
# Example
const obj = {
a: {
b: {
c: 1
}
},
b: {
c: {
d: Object.prototype.toString
}
},
c: 1
}
console.log(invokeMap(obj, Object.prototype.toString)) // [ '[object Object]', '[object Object]', '[object Number]' ]
console.log(invokeMap(obj, 'c.d')) // [ undefined, '[object Object]', undefined ]
← invoke isArguments →