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;
    }
}

/**
 * 循環参照の問題を解決する、mapの代わりにweakMapを使用し、メモリ解放する
 * 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);
}

// 関数型は直接返す、一般的に考慮しない
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。