js中创建的对象指向内存,所以在开发过程中,往往修改了一个对象的属性,会影响另外一个对象。

尤其是在angular框架中,dom是由数据驱动的,在增删改查对象的操作中,对象属性的继承关系是很让人头痛的!

我之前遇到的问题就是,在编辑页面,操作了对象数据,影响到了展示数据的展现!

我整理了两种深度克隆对象的方法,供大家参考!

 

深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

方案一:利用现代浏览器支持的JSON对象做一次中转,实现深度克隆。

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);

 

方案二:遍历自身,判断当前对象是obj还是list,克隆出新对象

function deepClone(obj)
{
  var o,i,j,k;
  if(typeof(obj)!=\" \" || obj===null)return obj;
  if(obj instanceof(Array))
  {
    o=[];
    i=0;j=obj.length;
    for(;i<j;i++)
    {
      if(typeof(obj[i])==\" \" && obj[i]!=null)
      {
        o[i]=arguments.callee(obj[i]);
      }
      else
      {
        o[i]=obj[i];
      }
    }
  }
  else
  {
    o={};
    for(i in obj)
    {
      if(typeof(obj[i])==\" \" && obj[i]!=null)
      {
        o[i]=arguments.callee(obj[i]);
      }
      else
      {
        o[i]=obj[i];
      }
    }
  }
  return o;
}
var scheduleClone = deepClone(schedule)
scheduleClone.data[0].contactList.phone[0] = 99999999999
console.log(\'方法1 深度克隆\')
console.log(scheduleClone)
console.log(JSON.stringify(schedule))
console.log(JSON.stringify(scheduleClone))

 

下面再分别讲解两种数据类型的克隆方式

一、原始类型克隆

1、数值的克隆

var x=1;
var y=x;
y=2;
console.log(x);  //1
console.log(y);  //2

2、字符串的克隆

var x=\"abc\";
var y=x;
y=\"def\";
console.log(x);  //abc
console.log(y);  //def

3、布尔值的克隆

var x = true;
var y = x;
y=false;
console.log(x);  //true
console.log(y);  //false

由于原始类型存储的是对象的实际数据,因此我们可以通过简单的复制方式即可得到正确的结果,而且不影响之前的对象。

 

二、对象类型克隆

1、数组的克隆

var x = [1,2,3];
var y = x;
console.log(y);  //[1,2,3]
y.push(4);
console.log(y);  //[1,2,3,4]
console.log(x);  //[1,2,3,4]

对象类型存储的是对象的引用地址,而把对象的实际内容单独存放,因为对象类型通常比较庞大,这是数据开销和内存开销优化的手段。因此我们不能像原始数据类型一样简单的赋值,而应该遍历数据中的每一个元素,将其中的每一个原始数据类型复制过去,做法如下:

var x = [1,2,3];
var y = [];
for (var i = 0; i < x.length; i++) {
    y[i]=x[i];
}
console.log(y);  //[1,2,3]
y.push(4);
console.log(y);  //[1,2,3,4]
console.log(x);  //[1,2,3]

2、对象的克隆

参照数组的克隆,我们采用同样的思想进行对象的克隆:

var x = {a:1,b:2};
var y = {};
for(var i in x){
    y[i] = x[i];
}
console.log(y);  //  {a: 1, b: 2}
y.c = 3;
console.log(y);  //  {a: 1, b: 2, c: 3}
console.log(x);  //  {a: 1, b: 2}

3. 函数的克隆

var x = function(){console.log(1);};
var y = x;
y = function(){console.log(2);};
x();  //1
y();  //2

由于函数对象克隆之后的对象会单独复制一次并存储实际数据,因此并不会影响克隆之前的对象。所以采用简单的复制“=”即可完成克隆。

收藏 打印