js中深浅拷贝有哪些方式?
(1)遍历赋值
(2)Object.create()
(2)JSON.parse()和JSON.stringify()
什么是深浅拷贝?
就是假如B复制了A,当修改A时,看B是否发生变化,如果B也跟着变了,这就是浅拷贝;
如果B没变,那就是深拷贝;
实例,如下是一个浅拷贝:
let a={key:1};
let b=a;
b.key=2;
console.log(a.key);//输出结果是2,当修改b时,a的key值也被修改了
浅拷贝
如下例子使用遍历的方式进行浅拷贝
实例2:浅拷贝例子,
data(){
return{
//定义一个对象obj
obj:{
a:"hello",
b:{
a:"world",
b:123,
c:['jack','tom',35]
}
}
}
},
mounted(){
//定义一个变量,使用simpleClone公用方法,传递参数,把obj复制给objCopy
var objCopy=this.simpleClone(this.obj);
//此时修改属性a的值
objCopy.a="hello2";
//修改属性b里面的a的值
objCopy.b.a="world2";
//此时我们打印出来看看,obj里面的属性值是否被改变了
console.log("obj",this.obj);
console.log("objCopy",objCopy);
//打印结果发现obj中的a属性值没有被改变,只是改变了b属性里面的a的值
// 这是因为b是一个对象,是一个引用类型
},
methods:{
//定义一个公用的方法
simpleClone(objNew){
//定义一个空对象
var obj={};
// 把参数复制给obj,这里通过for...in的方式
for(var i in objNew)
{
obj[i]=objNew[i];
// 读取属性值,如果是变量,所以要加[],这里i读取的是属性名,使用obj[i]是属性值,objNew通过遍历的方式把值赋值给obj[i]
}
return obj;//返回
}
}
上面例子中,obj里面的a属性没有被改变,而b属性里面的a属性值被改变了,是因为,a是原始值,而b是引用类型,传的是一个地址值,地址值导致还是会通过对应的地址去找到值,栈中存的是地址,堆中存的是数据,他们指向同一个数据源。请参考:https://blog.csdn.net/qq_42238554/article/details/120384786
使用Object.create()
来浅拷贝
使用现有的对象来提供新创建的对象的_proto_.可以理解为继承一个对象, 添加的属性是在原型下。
Object.create()也是浅拷贝。
如下代码:
var obj={
a:"hello",
b:{
a:"w",
b:123
},
c:[123,'jack']
}
let a=Object.create(obj);
a.a="hello1";
console.log(obj);
console.log(a);
显示结果:
通过Object.create()方式拷贝,我们发现,拷贝过来的值在_proto_原型上面,我们发现改变b属性中的a属性值,原来的obj里面的值也被改变了。
深拷贝
实例1,使用遍历的方式实现深拷贝
var obj={
a:"hello",
b:{
a:"w",
b:123
},
c:[123,'jack']
}
function deepClone(startObj,endObj)
{
var obj=endObj || {};
for(var i in startObj)
{
if(typeof startObj[i] === 'object')
{
obj[i]=startObj[i].constructor===Array?[]:{};
deepClone(startObj[i],obj[i])
}
else
{
obj[i]=startObj[i];
}
}
return obj;
}
var objCopy=deepClone(obj);
objCopy.b.a="w1";
console.log(obj);
console.log(objCopy);
打印结果:
实例2:使用JSON.parse和JSON.stringify深拷贝
var obj={
a:"hello",
b:{
a:"w",
b:123
},
c:[123,'jack']
}
var objCopy=JSON.parse(JSON.stringify(obj));
objCopy.b.a="w1";
console.log(obj);
console.log(objCopy);
把object类型转换成string类型,然后再转成object类型。