banner
SlhwSR

SlhwSR

热爱技术的一名全栈开发者
github
bilibili

深拷貝的各種實現

直接上代碼:

/**
 * JSON.parse(JSON.stringify(object))的問題在於
 *  1、忽略undefined
 *  2、忽略 Symbol
 *  3、不能序列化函數
 *  4、不能解決循環引用的物件
 * DeepClone1 -> 解決類型的問題,包括陣列
 * @param target
 */
export function DeepClone1(target) {
    if (typeof target === 'object') {
        // 考慮是否陣列
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
            // 不考慮原型屬性
            if (target.hasOwnProperty(key)) {
                // 遞迴複製
                cloneTarget[key] = DeepClone1(target[key]);
            }
        }
        return cloneTarget;
        // 非引用類型,直接返回即可
    } else {
        return target;
    }
}

/**
 * 解決循環引用的問題,用weakMap 替代 map, 內存釋放
 * 用map額外開闢內存空間,存儲當前物件和複製物件的關係
 */
export function DeepClone2(target, map = new Map()) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        if (map.get(target)) {
            return map.get(target);
        }
        map.set(target, cloneTarget);
        for (const key in target) {
            if (target.hasOwnProperty(key)) {
                cloneTarget[key] = DeepClone2(target[key], map);
            }
        }
        return cloneTarget;
    } else {
        return target;
    }
}

// 引用類型除了物件和函數,還有null和function,可封裝一個isObject
function isObject(target) {
    const type = typeof target;
    return target !== null && (type === 'object' || type === 'function');
}

/**
 * 按照是否可遍歷,將資料類型分類處理
 * 可遍歷:object/array/map/set
 * 不可遍歷:string/number/boolean/symbol、undefined/null、function、regex/date/error/math/JSON
 * 返回 [object Array]
 */
function getType(target) {
    return Object.prototype.toString.call(target);
}

// 函數類型,直接返回,一般不考慮
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。