lodash 의 clone Deep 에 대한 분석
본질 적 인 이 유 는 대상 이 주 소 를 인용 하기 때 문 입 니 다. 직접 할당 회 죠? 인용 주소 도 새 값 으로 복사 합 니 다.얕 은 복 제 는 대상 의 각 속성 을 순서대로 복사 하고 인용 주소 도 복사 합 니 다.깊 은 복사 본 은 원본 데 이 터 를 되 돌려 줍 니 다. 새 주 소 를 참조 하여 바 꿀 수 있 습 니 다.
lodash 의 clone Deep
입구
const CLONE_DEEP_FLAG = 1
const CLONE_SYMBOLS_FLAG = 4
function cloneDeep(value) {
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG)
}
핵심 논리
function baseClone(value, bitmask, customizer, key, object, stack) {
let result
const isDeep = bitmask & CLONE_DEEP_FLAG
const isFlat = bitmask & CLONE_FLAT_FLAG
const isFull = bitmask & CLONE_SYMBOLS_FLAG
if (customizer) {
result = object ? customizer(value, key, object, stack) : customizer(value)
}
if (result !== undefined) {
return result
}
if (!isObject(value)) {
return value
}
//
const isArr = Array.isArray(value)
// constructor
const tag = getTag(value)
if (isArr) {
//
result = initCloneArray(value)
// deep
if (!isDeep) {
return copyArray(value, result)
}
} else {
const isFunc = typeof value == 'function'
// Buffer.isBuffer, buffer
if (isBuffer(value)) {
return cloneBuffer(value, isDeep)
}
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
// proto
result = (isFlat || isFunc) ? {} : initCloneObject(value)
if (!isDeep) {
// deepclone isFlat 0, copySymbols, Symbols
return isFlat
? copySymbolsIn(value, copyObject(value, keysIn(value), result))
: copySymbols(value, Object.assign(result, value))
}
} else {
// func error, WeakMap
if (isFunc || !cloneableTags[tag]) {
return object ? value : {}
}
// tag true clone
result = initCloneByTag(value, tag, isDeep)
}
}
// Check for circular references and return its corresponding clone.
// 。
stack || (stack = new Stack)
const stacked = stack.get(value)
if (stacked) {
return stacked
}
stack.set(value, result)
// map clone
if (tag == mapTag) {
value.forEach((subValue, key) => {
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack))
})
return result
}
// set
if (tag == setTag) {
value.forEach((subValue) => {
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack))
})
return result
}
// TypedArray
if (isTypedArray(value)) {
return result
}
const keysFunc = isFull
? (isFlat ? getAllKeysIn : getAllKeys)
: (isFlat ? keysIn : keys)
const props = isArr ? undefined : keysFunc(value)
arrayEach(props || value, (subValue, key) => {
if (props) {
key = subValue
subValue = value[key]
}
// Recursively populate clone (susceptible to call stack limits).
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack))
})
return result
}
배열. 여 기 는 주로 exec 의 특수 배열 이 있 습 니 다.
function initCloneArray(array) {
const { length } = array
const result = new array.constructor(length)
// Add properties assigned by `RegExp#exec`.
// RegExp.exec
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index
result.input = array.input
}
return result
}
기타 방법
Underscore 라 이브 러 리 나 JSON. parse 등
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
함수형 프로그래밍에 대한 아주 간단한 소개"버즈워드"기능 프로그래밍(FP), 구성, 포인트 프리 등을 들었는데 완전히 길을 잃었다면… 혼자가 아닙니다. 다음은 구성하고 기능적이고 포인트 프리 스타일의 프로그래밍을 따를 경우 할 수 있는 일에 대한 간략한 정...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.