JavaScript 深浅拷贝

深拷贝: 深拷贝即创建新的内存地址保存值(互不影响)
浅拷贝: 共用同一内存地址,你改变我也跟着变

// Array.prototype.concat  深拷贝用法
var arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("数组的原始值:" + arr1 ); //  ["1","2","3"]
console.log("数组的新值:" + arr2 ); //  ["1","9","3"]
//Array.prototype.slice  深拷贝用法
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("数组的原始值:" + arr1 ); //  ["1","2","3"]
console.log("数组的新值:" + arr2 ); //  ["1","9","3"]
// Array.prototype.concat   浅拷贝用法
var arr1 = [{"name":"weifeng"},{"name":"boy"}];   //原数组
var arr2 = [].concat(arr1);   //拷贝数组
arr1[1].name="girl";
console.log(arr1);   // [{"name":"weifeng"},{"name":"girl"}]
console.log(arr2);   //[{"name":"weifeng"},{"name":"girl"}]
// Array.prototype.slice  浅拷贝用法
var a1=[["1","2","3"],"2","3"] , a2;
a2=a1.slice(0);
a1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(a2[0][0]);  //影响到了a2

var b1=[["1","2","3"],"2","3"] , b2;
b2=b1.slice(0);
b1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(b2[0][0]);  //影响到了a2

总结:slice和concat两个方法,可深拷贝可浅拷贝,取决于拷贝的是基本数据还是引用数据(适用于不包含引用对象的一维数组的深拷贝)

// Object.assign()   用法
// (1)合并多个对象
const obj1 = { name: 'kattes',age: 24}
const obj2 = { address: '四川成都', hobby: 'code' }
const obj3 = { workingYears: 5}
const obj = Object.assign(obj1, obj2, obj3)
console.log(obj) //{ name: 'kattes', age: 24, address: '四川成都', hobby: 'code', workingYears: 5}
// (2)克隆对象(浅)
const obj = { name: 'kattes' ,age: 24}
const obj1 = Object.assign({},obj)
console.log(obj1) //{ name: 'kattes' ,age: 24}
// (3)为对象添加多个方法
Object.assign(classOne.prototype, {
    method1(arg1, arg2) {},
    method2() {}
});
// js原始方法
classOne.prototype.method1 = function (arg1, arg2) {};
classOne.prototype.method2 = function () {};

总结: Object.assign是浅拷贝(只会深拷贝一层,不会递归拷贝,所以依然是浅拷贝,但此方法如果用于简单的基本数据拷贝,则就相当于深拷贝)

//  JSON.parse(JSON.stringify(obj))
let obj = {
    a: 123,
    b: {
        c: 456,
        d: {
            e: 789
        }
    }
};
let copy = JSON.parse(JSON.stringify(obj));
// 对obj对象无论怎么修改,都不会影响到copy对象
obj.b.c = 'hello';
obj.b.d.e = 'world';
console.log(copy);  // {a: 123, b: {c: 456, d: {e: 789}}}

总结: JSON.parse(JSON.stringify()) 此方法适用于简单值、对象和数组三种类型的深拷贝,不适用于变量、函数或对象实例的拷贝 (函数会丢失,原型链会丢失)

总结如下两种拷贝函数,如有需要,请白嫖拿走:(不适用于复杂的场景)

// 深拷贝    复制所有的属性
function deepClone(source){
    const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
    for(let keys in source){ // 遍历目标
      if(source.hasOwnProperty(keys)){//hasOwnProperty方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性
        if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
          targetObj[keys] = source[keys].constructor === Array ? [] : {};
          targetObj[keys] = deepClone(source[keys]);
        }else{ // 如果不是,就直接赋值
          targetObj[keys] = source[keys];
        }
      }
    }
    return targetObj;
}
// 浅拷贝  复制所有属性
function shallowCopy(obj) {
  var copy = {};
  // 只复制可遍历的属性
  for (key in obj) {
      // 只复制本身拥有的属性
      if (obj.hasOwnProperty(key)) {
          copy[key] = obj[key];
      }
  }
  return copy;
}

jQuery.extend() 和 lodash _.baseClone() 两种拷贝 这里就不探究了,如有需要,留言告知

总结: 开发时合理根据自己需求来使用以上方法就对了!!! 文章在此就结束啦! 如果你有什么更好的建议,请留言告知,相互学习才能更快进步!

你可能感兴趣的:(JavaScript 深浅拷贝)