利用深度/廣度優先遍歷手動實現JavaScript對象的深度拷貝

引言

搜索JavaScript對象的深度拷貝,每每會冒出JSON轉換和遞歸拷貝大法。但遇到大數據量,它們都有調用棧爆棧的風險
今天,咱們嘗試利用樹的利用深度/廣度優先遍從來實現對象的深度拷貝。如下代碼在chrome環境下所有測試經過。chrome

深度優先遍歷實現對象的深度拷貝

深度優先遍歷對象,利用棧作中間節點緩存緩存

function deepCopy(orginObject) {
    if (orginObject == null || typeof orginObject !== 'object') {
        return;
    }
    console.log('starting')
    const resultObject = {}
    const rootKey = Symbol('root');
    //深度遍歷須要建立棧
    const stack = [];
    for (let key of Object.keys(orginObject)) {
        stack.push({
            key: key,//屬性名
            value: orginObject[key],//value屬性記錄當前節點下屬數據
            parent: resultObject//記錄節點在resultObject中的位置
        })
    }

    while (stack.length) {
        const currentNode = stack.pop();
        const parent = currentNode.parent;
        const currentKey = currentNode.key;
        const currentValue = currentNode.value;
        //如果無下屬對象,返回其值
        if (currentValue == null || typeof currentValue !== 'object') {
            parent[currentKey] = currentValue;
        } else {
            //若下屬值是對象,將子節點壓入棧中
            parent[currentKey] = Object.prototype.toString.call(currentValue) === '[object Array]'?[]:{};
            for (let key of Object.keys(currentValue)) {
                console.log('loop:' + key, currentValue[key])
                stack.push({
                    key: key,
                    value: currentValue[key],
                    parent: parent[currentKey]
                })
            }
        }
    }
    return resultObject;
}
var copyObj = deepCopy({ a: { b: 1, d: { e: 6 } }, c: 3 });
console.log(copyObj);

廣度優先遍歷實現對象的深度拷貝

廣度優先遍歷對象,利用隊列作中間節點緩存oop

function deepCopy(orginObject) {
    if (orginObject == null || typeof orginObject !== 'object') {
        return;
    }
    console.log('starting')
    const resultObject = {}
    const rootKey = Symbol('root');
    //深度遍歷須要建立棧
    const queue = [];
    for (let key of Object.keys(orginObject)) {
        queue.push({
            key: key,//屬性名
            value: orginObject[key],//value屬性記錄當前節點下屬數據
            parent: resultObject//記錄節點在resultObject中的位置
        })
    }

    while (queue.length) {
        const currentNode = queue.shift();
        const parent = currentNode.parent;
        const currentKey = currentNode.key;
        const currentValue = currentNode.value;
        //如果無下屬對象,返回其值
        if (currentValue == null || typeof currentValue !== 'object') {
            parent[currentKey] = currentValue;
        } else {
            //若下屬值是對象,將子節點壓入棧中
            parent[currentKey] = Object.prototype.toString.call(currentValue) === '[object Array]'?[]:{};
            for (let key of Object.keys(currentValue)) {
                console.log('loop:' + key, currentValue[key])
                queue.push({
                    key: key,
                    value: currentValue[key],
                    parent: parent[currentKey]
                })
            }
        }
    }
    return resultObject;
}
var copyObj = deepCopy({ a: { b: 1, d: { e: 6 } }, c: 3 });
console.log(copyObj);
相關文章
相關標籤/搜索