读书人

js数组的深度克隆求大神。该如何处理

发布时间: 2012-03-19 22:03:05 作者: rapoo

js数组的深度克隆,求大神。
数组属于引用类型,有些时候我们需要克隆一个副本出来使用。简单类型的好办。但数组里包含了复杂类型的就有点不太好办了。看2个列子。

JScript code
 var arr = new Array(1,2,3); //原始数组。        var newarr = new Array();        newarr = arr.concat();       newarr[0] = newarr[0] + 100;       alert("克隆出来的数组的第一个元素的值为:" + newarr[0] + ",原始数组的值为:" + arr[0]);      //这样对于简单的数据类型可以达到完全克隆的效果。新元素的值为101 ,原始数组里的值不变。1。      //但是,请看下面。

JScript code
//上面的方法达到了简单数组克隆的目地了。现在新的问题来了        var arr = new Array(); //原始数组。        var a = { name: "张三", age: 20 };        var b = { name: "李四", age: 30 };        var c = { name: "王武", age: 40 };        arr.push(a); arr.push(b); arr.push(c);        var newarr = new Array();        newarr = arr.concat();//复制        //删除其最后一个元素。        newarr.pop();        //更改其中李四的年龄为100        newarr[1].age = 100;        //打印结果看下。        alert("复制的数组的长度为:" + newarr.length + ",李四的年龄为:" + newarr[1].age);        alert("原始的数组的长度为:" + arr.length + ",李四的年龄为:" + arr[1].age);       // 现在新元素的长度变成 2了。而并没有影响到原始数组的数组长度,原始数组的数组长度依然为3.但:数组当中的第二个元素,也就是李四的年龄。。。在我们更改了复制的新数组里面的年龄时,,,原始数组也变了。。这个不是我们想要的结果。。。。


[解决办法]
克隆对象的方法:
function objClone(myObj){
if(typeof(myObj) != 'object') return myObj;
if(myObj == null) return myObj;
var myNewObj = new Object();
for(var i in myObj)
myNewObj[i] = objClone(myObj[i]);
return myNewObj;
}
Array.prototype.clone=function(){//为数组添加克隆自身方法,使用递归可用于多级数组
var newArr=new Array();
for(var i=0;i<=this.length-1;i++)
{
var itemi=this[i];
if(itemi.length && itemi.push) itemi= itemi.clone();//数组对象,进行递归
else if(typeof(itemi)=="object") itemi=objClone(itemi);//非数组对象,用上面的objClone方法克隆
newArr.push(itemi);
}
return newArr;
}

基本可以达到完美克隆,length属性也不会丢失(单独用objClone方法也可以克隆数组的所有成员,但是丢失length属性)
使用方式:arr.clone();
[解决办法]
将就着用。
JScript code
Object.prototype.clone = function () {    var o = {};    for (var i in this) {        o[i] = this[i];    }    return o;};Array.prototype.clone = function () {    var arr = [];    for (var i = 0; i < this.length; i++)    if (typeof i !== 'object') {        arr.push(i);    } else {        arr.push(i.clone());    }    return arr;};var p1 = {    name: 'Rattz',    age: 20,    hello: function () {        return "I'm " + name;    }};var p2 = p1.clone();p2.age++;alert(p1.age);var arr1 = [12, 'a', p1,{}];var arr2 = arr1.clone();arr2[2].name = 'Mike';alert(arr1[2].name);
[解决办法]
如果一定要实现clone方法,非扩展原型及不迭代的方法实现如下

JScript code
var cloneOpr = {    cloneObj: function (obj) {        var newObj = [];        for (var i in obj) {            newObj[i] = obj[i];        }        return newObj;    },    cloneArr: function (arr) {        var newArr = [];        for (var i = 0; i < arr.length; i++) {            if (typeof arr[i] === 'object') {                newArr.push(this.cloneObj(arr[i]));            } else {                newArr.push(this[i]);            }        }        return newArr;    }};var obj = {    id: 1};var obj2 = cloneOpr.cloneObj(obj);obj2.id = 'Mike';alert(obj.id);alert(obj2.id);var arr = [1, 'a', {id: '20'}];var arr2 = cloneOpr.cloneArr(arr);arr[2].id = "new id";alert(arr[2].id);alert(arr2[2].id); 

读书人网 >JavaScript

热点推荐