# transform
# Description
reduce 的替代方法;此方法将转换 object 对象为一个新的 accumulator 对象,结果来自 iteratee 处理自身可枚举的属性。 每次调用可能会改变 accumulator 对象。如果不提供 accumulator,将使用与 [[Prototype]] 相同的新对象(即原型一致)。iteratee 调用 4 个参数:(accumulator, value, key, object)。如果返回 false,iteratee 会提前退出。
# Params
(object, iteratee, accumulator)
# Return
{*}
# Depend
import arrayEach from './.internal/arrayEach.js'
import baseForOwn from './.internal/baseForOwn.js'
import isBuffer from './isBuffer.js'
import isObject from './isObject.js'
import isTypedArray from './isTypedArray.js'
arrayEach 源码分析
baseForOwn 源码分析
isBuffer 源码分析
isObject 源码分析
isTypedArray 源码分析
# Code
function transform(object, iteratee, accumulator) {
const isArr = Array.isArray(object)
const isArrLike = isArr || isBuffer(object) || isTypedArray(object)
if (accumulator == null) {
const Ctor = object && object.constructor
if (isArrLike) {
accumulator = isArr ? new Ctor : []
}
else if (isObject(object)) {
accumulator = typeof Ctor === 'function'
? Object.create(Object.getPrototypeOf(object))
: {}
}
else {
accumulator = {}
}
}
(isArrLike ? arrayEach : baseForOwn)(object, (value, index, object) =>
iteratee(accumulator, value, index, object))
return accumulator
}
# Analyze
在没有传入 accumulator
或者 accumulator
为 null
时,会给 accumulator
一个初始值
如果是 类数组,则判断 object
是否为 array
,如果是 array
则为 new Ctor
,其他情况则使用空数组
如果是 对象,则会判断 Ctor
是不是 function
类型,如果是 function
类型,则使用 Object.create
得到一个和传入的 object
原型一致的对象;如果不是 function
类型,则使用空对象
其他情况下都使用 空对象
在最终迭代时,会根据是 类数组还是其他的确定迭代方法,类数组使用 arrayEach
,其他情况下使用 baseForOwn
,调用 iteratee
迭代器,可直接修改 accumulator
对象
# Remark
Object.create() MDN (opens new window) 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
Object.getPrototypeOf() MDN (opens new window) 方法返回指定对象的原型(内部 [[Prototype]] 属性的值)。
# Example
const obj = {
a: 1,
b: 2,
c: 3,
d: 4
}
const func = (result, v, i, obj) => {
result[i] = obj[i]
}
const temp = {
obj: {}
}
console.log(transform(obj, func)) // { a: 1, b: 2, c: 3, d: 4 }
console.log(transform(obj, func, temp.obj)) // { a: 1, b: 2, c: 3, d: 4 }
console.log(temp) // { obj: { a: 1, b: 2, c: 3, d: 4 } }