深拷贝和浅拷贝

2019-03-21  本文已影响0人  磨人的磨磨虫

在说深拷贝之前,先说下引用类型,比如

let a=[0,1,2,3,4],
    b=a;
console.log(a===b);//true
a[0]=1;
console.log(a,b);//[1,1,2,3,4],[1,1,2,3,4]

这里修改了a,但是b也紧接被修改了,这是因为声明a的时候建立一个栈,而b只是引用指向了a的栈,所以当你修改了a的时候,b的指向还是保持不变的指向的是a,把栈比做一个仓库,而a是那个仓库,b比作一个代理商卖a仓库里的东西,上述例子可以称为 浅拷贝;

深拷贝就是需要不影响a的情况下拷贝出来的新栈.实现深拷贝的方法有几种,如下:

第一种:递归复制

// 函数式缓存
function memoize(f){
  //建立缓存
  var cache={}
  return function(){
      var arg_str = JSON.stringify(arguments);
      //是否缓存过此键 否则重新计算一次
      cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
      return cache[arg_str];
  }
}

var deepClone=memoize(function(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;
})


let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

or

//写在原型链上
var ss={
    a:1,
    b:{
        c:2
    },
    name:'zzh',
    list:[1,3,6,4,4]
}

Object.prototype.depthCopy=function(){
    let _this=this

    let recursion=(obj)=>{ 
        let newObj=Array.isArray(obj)?[]:{};
        
        if(obj&&(typeof obj).toLowerCase() == 'object'){
            for(let k in obj){
                if(obj.hasOwnProperty(k)){
                    if((typeof obj[k]).toLowerCase() == 'object'){
                        newObj[k]=recursion(obj[k])
                    }else{
                        newObj[k]=obj[k]
                    }
                }

            }

        }
        
        return newObj
    }

    return recursion(_this)
}

var zz=ss.depthCopy()
var xx=ss
console.log(zz==ss)
console.log(xx==ss)

第二种:JSON.stringify 和 JSON.parse

let a=[0,1,2,3]
b=JSON.parse(JSON.stringify(a))
a[0]=1
console.log(a)//[1,1,2,3]
console.log(b)//[0,1,2,3]

第三种:jq.extend的

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
上一篇 下一篇

猜你喜欢

热点阅读