实现一个函数clone,可以对js中得基本数据类型进行值复制

    /**
 * 对象克隆
 * 支持基本数据类型及对象
 * 递归方法
 */
// 方法一:
function clone(obj) {
	var o;
	switch (typeof obj) {
		case "undefined":
			break;
		case "string":
			o = obj + "";
			break;
		case "number":
			o = obj - 0;
			break;
		case "boolean":
			o = obj;
			break;
		case "object": // object 分为两种情况 对象(Object)或数组(Array)
			if (obj === null) {
				o = null;
			} else {
				if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") {
					o = [];
					for (var i = 0; i < obj.length; i++) {
						o.push(clone(obj[i]));
					}
				} else {
					o = {};
					for (var k in obj) {
						o[k] = clone(obj[k]);
					}
				}
			}
			break;
		default:
			o = obj;
			break;
	}
	return o;
}
//方法二:解决父子循环引用问题
// 深拷贝 解决父子循环引用问题
function deepCopy2(obj, parent=null) {
    //创建一个新对象
    let result = {};
    let keys = Object.keys(obj),
         key = null,
         temp = null,
         _parent = parent;
    //该字段有父级则需要追溯该字段的父级
    while(_parent) {
        //如果该字段引用了它的父级,则为循环引用
        if(_parent.originParent === obj) {
            //循环引用返回同级的新对象
            return _parent.currentParent;
        }
        _parent = _parent.parent
    }
    for(let i=0,len=keys.length;i<len;i++) {
        key = keys[i]
        temp = obj[key]
        // 如果字段的值也是一个新对象
        if(temp && typeof temp === 'object') {
            result[key] = deepCopy2(temp, {
                //递归执行深拷贝,将同级的待拷贝对象与新对象传递给parent,方便追溯循环引用
                originParent: obj,
                currentParent: result,
                parent: parent
            });
        } else {
            result[key] = temp;
        }
    }
    return result;
}

const obj1 = {
    x:1
}
obj1.z = obj1;

const obj2 = deepCopy2(obj1);

// 方法三:
// 深拷贝 解决兄弟循环引用问题
function deepCopy3(obj) {
    // hash表,记录所有的对象的引用关系
    let map = new WeakMap();
    function dp(obj) {
        let result = null;
        let keys = Object.keys(obj);
        let key = null,
            temp = null,
            existobj = null;

        existobj = map.get(obj);
        //如果这个对象已经被记录则直接返回
        if(existobj) {
            return existobj;
        }

        result = {}
        map.set(obj, result);

        for(let i =0,len=keys.length;i<len;i++) {
            key = keys[i];
            temp = obj[key];
            if(temp && typeof temp === 'object') {
                result[key] = dp(temp);
            }else {
                result[key] = temp;
            }
        }
        return result;
    }
    return dp(obj);
}

const obj= {
    a: {
        name: 'a'
    },
    b: {
        name: 'b'
    },
    c: {

    }
};
c.d.e = obj.a;

const copy = deepCopy3(obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值