JavaScript深拷贝与浅拷贝的区别和实现方式

如何区分深拷贝和浅拷贝呢,简单来说对象B拷贝了对象A,如果对象A和对象B共用一个对象,对象B改变对象A跟着改变这就是浅拷贝;但如果对象B拷贝了对象A,但是对象A和对象B是分开的,那么就是深拷贝

基本数据类型的拷贝,名字和值都会储存在栈内存中,不存在深浅拷贝(Number,Boolean,String)

var a = 1;
b = a ;
b = 3
console.log(a)     // 1

深拷贝本身只针对较为复杂的object类型数据。

如果是引用数据类型,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个停用地址指向堆内存的值

var a = {name: 'abc'}
var b = {age: 18}
变量名 堆内地址
a 0x666
b 0x999
堆地址
0x666
0x999

浅拷贝

var a = {name:'abc',age:18}
var b = a
变量名 堆内地址
a 0x666
b 0x666
堆地址
0x666

深拷贝

let obj1 = {
  a: 1,
  b: 2
}
let obj2 = {
  a: obj1.a,
  b: obj1.b
}
变量名 堆内地址
obj1 0x666
obj2 0x666
堆地址
0x666
0x999

浅拷贝方法

  • for···in只循环第一层
function simpleCopy(obj1) {
 var obj2 = Array.isArray(obj1) ? [] : {};
  for (let i in obj1) {
  obj2[i] = obj1[i];
 }
  return obj2;
}

只循环了第一层,如果对象有多层,那么从第二层开始也是属于浅拷贝

Object.assign方法

var obj = {
   name: 'abc',
   age: 2
}

方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

深拷贝方法

  • 使用递归拷贝所有层级的属性
function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}
  • 通过JSON对象来实现深拷贝
function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}
  • 使用扩展运算符实现深拷贝
var car = {brand: "BMW", price: "380000", length: "5米"}
var car1 = { ...car, price: "500000" }
posted @ 2021-04-14 13:16  亓亓哟  阅读(153)  评论(0编辑  收藏  举报