深拷贝的实现方式

本文介绍了三种JavaScript中实现深度拷贝的方法:通过JSON对象的stringify和parse方法,递归复制源对象到目标对象,以及使用数组的forEach和ECMAScript 5的Object.*函数。其中,JSON方法不适用于包含DOM对象或某些特定类型的对象,递归复制方法可能产生功能性错误,而第三种方案在处理特定类型的值时也会遇到问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方案一:利用现代浏览器支持的JSON对象做一次中转,实现深度克隆。(IE6、IE7不支持原生JSON对象,可载入json2.js补丁来达到兼容)感谢rekey提供此方案。JSON.stringify()与JSON.parse()详细信息请点击这里
var deepClone = function (obj) {
    var _tmp,result;
    _tmp = JSON.stringify(obj);
    result = JSON.parse(_tmp);
    return result;
}
var obj1 = {family:{brother:"wangzhipeng",father:"wanglicai",mother:"sunaiyun"},name:"gino",sex:"male",age:"27"};
var obj2 = deepClone(obj1);
obj1.family.brother = "close";
console.log(obj1); 
console.log(obj2); 
方案二:确定参数类型为object (这里仅指object literal、Array literal)后,复制源对象的键/值到目标对象,否则直接返回源对象。

注:下面这个函数只能说基本满足生产需求,如果参数是Dom对象、new Object ()的话,就会产生功能性错误,要兼容参数的所有数据类型,请点击这里

var deepClone = function fnDeepClone(obj){
    var result = typeof obj.splice === 'function'?[]:{},
    key;
    if (obj && typeof obj === 'object'){
        for (key in obj ){
            if (obj[key] && typeof obj[key] === 'object'){
                result[key] = fnDeepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即再把某个值对象复制一份到新的对象的对应值中
            }else{
                result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键/值到新对象对应的键/值中
            }
            
        }
        return result;
    }
    return obj;
    

}

//test array
var arry1= ["a","b","c","d"];
var arry2 = deepClone(arry1);
arry1.pop();
console.log(arry1);
console.log(arry2);

//test object
var obj1 = {name:"gino",sex:"male",age:27,favorite:"pingpang",family:{brother:"zhipeng",mother:"SunAiyun",father:"WangLicai"}};
var obj2 = deepClone(obj1);
obj1.family.brother = "close";
console.log(obj1);
console.log(obj2);
方案三:利用数组的Array.prototype.forEach和其他一些ECMAScript 5中的Object.*函数。经测试,当值的类型为object的时候,会出现功能错误。个人水平有限,没看懂这个函数,如有朋友能帮忙修正下此函数,万分感激。 链接
var deepClone = function (o){
  var copy = Object.create( Object.getPrototypeOf(o) );
  var propNames = Object.getOwnPropertyNames(o);
 
  propNames.forEach(function(name){    
    var desc = Object.getOwnPropertyDescriptor(o, name);   
    Object.defineProperty(copy, name, desc);        
  });
 
  return copy;
}
 
var obj1 = {family:{brother:"wangzhipeng",father:"wanglicai",mother:"sunaiyun"},name:"gino",sex:"male",age:"27"};
var obj2 = deepClone(obj1);
obj1.sex = "close";
console.log(obj1); 
console.log(obj2); 
设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。 设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值