在说深拷贝之前,先说下引用类型,比如
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);
网友评论