原生 - 深复制封装

//ES5
function cloneObject(sourceObj,targetObj){
    //如果目标对象没传参则进入
    if(!targetObj){
        //如果对象类型是事件正则类型
        if(sourceObj.constructor === RegExp){
            //创建一个类型为正则的目标对象
            targetObj = new RegExp(sourceObj.source,sourceObj.flags);

        //如果是非正则类型
        }else{
            //创建一个源对象类型
            targetObj = new sourceObj.constructor();
        }
    }
    //将源对象的所有属性名以数组的形式获取
    var names = Object.getOwnPropertyNames(sourceObj);
    //对names做一个循环
    for(var i = 0 ; i < names.length ; i++){
        //根据每一个属性名获取该对象的描述对象(是否枚举、可写、可删除、可修改,value是值)
        var desc = Object.getOwnPropertyDescriptor(sourceObj,names[i]);

        //判断描述对象的value是有引用的对象类型,并且非空
        if(typeof desc.value === "object" && desc.value !== null){
            //这种情况就需要进一步对他的子对象进行复制(克隆寻找子元素在进行复制)
            //执行克隆函数,将原对象以第一个参数传入,第二个目标对象不传(不传的话默认会走创建源对象)
            //最终会返回复制好的目标对象,例如定义返回的变量名为values
            var values = cloneObject(desc.value);
            Object.defineProperty(targetObj,names[i],{
                enumerable:desc.enumerable,
                writable:desc.writable,
                configurable:desc.configurable,
                value:values
            })
            //否则(value是非对象类型或者是空,进入)
        }else{
            //直接给目标对象增加这个属性名,并且将这个对象的描述对象赋值给这个新的属性
            Object.defineProperty(targetObj,names[i],desc);
        }
    }
    return targetObj;
}


//ES6
const cloneObj = ((sourceObj, targetObj) => {
    !targetObj
    	? sourceObj.constructor === RegExp
    		? targetObj = new RegExp(sourceObj.source,sourceObj.flags) 
            : targetObj = new sourceObj.constructor() 
        : targetObj
    Object.getOwnPropertyNames(sourceObj).map((item, index) => {
        let desc = Object.getOwnPropertyDescriptor(sourceObj,Object.getOwnPropertyNames(sourceObj)[index])
        desc.value !== null && typeof desc.value === 'object'
        	? Object.defineProperty(targetObj, Object.getOwnPropertyNames(sourceObj)[index], {
                enumerable: desc.enumerable,
                writable: desc.writable,
                configurable: desc.configurable,
                value: cloneObj(desc.value)
            })
            : Object.defineProperty(targetObj, Object.getOwnPropertyNames(sourceObj)[index], desc)
    })
    return targetObj
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值