浅拷贝和深拷贝(数组和对象的深浅拷贝)

 浅拷贝

只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做浅拷贝(浅复制)

对象浅拷贝:

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 100, c: 30 } <-- b 被改到了
console.log(obj2);
// { a: 10, b: 100, c: 30 }

数组浅拷贝:

var arr = ["One","Two","Three"];
var arrto = arr;
arrto[1] = "test";
console.log("数组的原始值:" + arr + "<br />");//数组的原始值:One,test,Three
console.log("数组的新值:" + arrto + "<br />");//数组的新值:One,test,Three

深拷贝

深拷贝:在计算机中开辟了一块新的内存地址用于存放复制的对象。(对属性中所有引用类型的值,遍历到是基本类型的值为止。 )

对象的深拷贝

方式一:简单的对象(不算是真正的深拷贝)

var a = {name:'1',age:'2',color:'3'};
function copyObj(a) {
var b = {};
for(var key in a) {
b[key] = a[key];
}
return b;
}
var c = copyObj(a);
c.name = '5';
console.log('c',c);
console.log('a',a);

方式二: ES6  let {...b} = a

方式三:复杂对象,利用递归来实现深拷贝(最常用的)

function cloneObject (obj) {
     var newObj = {}  //如果不是引用类型,直接返回
      if (typeof (obj) !== 'object') {
          return obj
     }
     //如果是引用类型,遍历属性
    else{
        for (var attr in obj) {
        //如果某个属性还是引用类型,递归调用
        newObj[attr] = cloneObject(obj[attr])
                }
       }
    return newObj
}

我们先判断它是否为引用类型,如果不是,直接返回 
如果是,循环遍历该对象的属性,如果某个属性还是引用类型,则针对该属性再次调用cloneObject函数 

方式四:用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。(最常用的)

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);
// { body: { a: 10 } } <-- 沒被改到
console.log(obj2);
// { body: { a: 20 } }
console.log(obj1 === obj2);
// false
console.log(obj1.body === obj2.body);
// false

数组深拷贝

ES5:slice()和concat()

var a = [1,2,3];
var b = a.slice(0);
var c = a.concat();
b.push(4);
c.push(5);
a; //[1,2,3]
b; //[1,2,3,4]
c; //[1,2,3,5]

ES6:   let [...b] = a;

猜你喜欢

转载自blog.csdn.net/xiasohuai/article/details/81086480