浅拷贝、深拷贝及循环引用

浅拷贝:是把原来的数组(对象)直接赋值给另个数组(对象),新的数组(对象)只是原来数组(对象)的一个引用,拷贝后指向通一个对象的实例,只拷贝一层,并且不能对对象中的子属性拷贝,彼此操作会产生影响
深拷贝:将原对象中的属性逐一复制,而且将原对象中的对象属性也逐一的递归复制到另一个对象中,拷贝的是值,而并非引用,彼此操作不会产生影响

总结:假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明是浅拷贝,如果B没变,那就是深拷贝。深入点来说,就是B复制了A,如果B复制的是A的引用,那就是浅拷贝,如果B复制的是A的本体,那就是深拷贝。

深拷贝实现方式
Object.assign()多层是浅拷贝,一层是深拷贝

//浅拷贝
eg:var obj = {a:1,arr:[2,3]}
var newObj = Object.assign({}, obj);
newObj.arr[1] = 10
console.log(newObj)  {a:1,arr:[2,10]}
console.log(obj) {a:1,arr:[2,10]}

//深拷贝
eg: var obj1 = {a:1,b:2}
var newObj1 = Object.assign({}, obj1);
newObj1.b = 20
console.log(newObj1)  {a:1,b:20}
console.log(obj1) {a:1,b:2}

判断是否是对象

function isObject(obj){
  return Object.prototype.toString.call(obj) === '[object Object]'  || Object.prototype.toString.call(obj) === '[object Array]'
}

JSON.stringify JSON.parse

eg:function deepObj(obj){
    if (!isObject(obj)) return 
        var newObj =  JSON.parse(JSON.stringify(obj))
        return newObj
  }

for…in(递归方法)

eg: function deepCopy(obj){
    if (!isObject(obj)) return 
    var newObj = Array.isArray(obj)?[]:{}
    for(var key in obj){
        if (obj.hasOwnProperty(key)) {
          if(isObject(obj[key])){
              newObj[key] = deepCopy(obj[key]) 
          }else{
              newObj[key] = obj[key];
           }
        }
    }
    return newObj
}

在深拷贝的过程中,大家有没有出现过这样的情况
对象的某个属性,正是这个对象本身,此时我们如果进行深拷贝,可能会在子元素->父对象->子元素…这个循环中一直进行,导致栈溢出,造成了循环引用,比如

const obj = {
    a:1,
      b:2
}
obj.c = obj
const obj1 =  deepCopy(obj); //栈溢出

//使用Map函数

function deepCopy(obj,map = new Map()){
    if (!isObject(obj)) return 
    var newObj = Array.isArray(obj)?[]:{}
    if(map.get(obj)){ 
      return map.get(obj); 
    } 
    map.set(obj,newObj);
    for(var key in obj){
        if (obj.hasOwnProperty(key)) {
            if (isObject(obj[key])) {
                newObj[key] = deepCopy5(obj[key],map);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    return newObj;
}
const obj1 = {
        x:1,
        y:2,
        d:{
            a:3,
             b:4
         }
    }
  obj1.z = obj1;
  const obj2 = deepCopy(obj1);
  console.log(obj2)
//node 输出{ x: 1, y: 2, d: { a: 3, b: 4 }, z: [Circular] }
//控制台输出{x: 1, y: 2, d: {…}, z: {…}}

我们看到,Circular 代表obj1的属性循环引用了自身.ob1j的属性等于输入对象obj1自己。 通过Circular直接告知是循环引用自身。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值