破解递归爆栈的深拷贝

破解递归爆栈的深拷贝

https://juejin.im/post/5c45112e6fb9a04a027aa8fe#heading-11

递归爆栈问题

https://blog.csdn.net/weixin_34151004/article/details/88452339

函数 caller 运行时,调用其他函数 called ,js会在调用栈中新开一个调用帧存储作用域和上下文信息,而caller的调用帧信息仍需要保存。而内存中调用栈存储信息有限,递归情况下,如果递归层次过深会导致调用栈耗光而引起stack overflow —— 爆栈。

----------------------------------------------------------

递归深拷贝

function clone(source) {
    var target = {};
    for(var i in source) {
        if (source.hasOwnProperty(i)) {
            if (typeof source[i] === 'object') {
                target[i] = clone(source[i]); // 注意这里
            } else {
                target[i] = source[i];
            }
        }
    }

    return target;
}

破解递归爆栈的深拷贝

function cloneDeep5(x) {
    const root = {};

    //
    const loopList = [
        {
            parent: root,
            key: undefined,
            data: x,
        }
    ];

    while(loopList.length) {
        // 广度优先
        const node = loopList.pop();
        const parent = node.parent;
        const key = node.key;
        const data = node.data;

        // 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
        let res = parent;
        if (typeof key !== 'undefined') {
            res = parent[key] = {};
        }

        for(let k in data) {
            // if (data.hasOwnProperty(k)) { // 改用call方法判断原因见后面
        if(Object.prototype.hasOwnProperty.call(data, "b"))
                if (typeof data[k] === 'object') {
                    // 下一次循环
                    loopList.push({
                        parent: res,
                        key: k,
                        data: data[k],
                    });
                } else {
                    res[k] = data[k];
                }
            }
        }
    }

    return root;
}

作者:木易杨说
链接:https://juejin.im/post/5c45112e6fb9a04a027aa8fe
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
data.hasOwnProperty(k) 改用
Object.prototype.hasOwnProperty.call(data, "b") 原因
var myObject = Object.create( null );
myObject.b = 2;

("b" in myObject); 
// true

myObject.hasOwnProperty( "b" );
// TypeError: myObject.hasOwnProperty is not a function

测试 cloneDeep5 

let param3 = Object.create(null);
param3.a ='xa1';
param3.c = function(){
    console.log(this.a);
}

let param4 = cloneDeep5(param3); 
console.log(param4);
原文地址:https://www.cnblogs.com/jcz1206/p/11224334.html