浅拷贝
let a = 10;
let b=a;
a=20
console.log(b)//10
1,由于a和b基本类型并且都是在栈中的,它们分别进行保存,所以这里输出的b还是10
2,通过内存可以看出,它们的两个值是独立的,更改其中一个不会影响另外一个。如下图
二,引用类型
let a=[1,2,3]
let b=a;
//这里通过更改a里面的第一个元素
a[0]=10
console.log(b)//[10,2,3]
原因: 1,由于是一个引用类型,它存的就不是这个数据,而是一个内存地址; 2,这里声明了一个变量a,但它的值并不是直接存了这个数组,而是内存地址,这个时候它会在堆中开辟一块内存存储这个数据[1,2,3]; 3,a里面存放的就是这个地址,变量a就根据这个地址进行查找; 4,接着在声明了一个变量b,由于a和b引用的是同一个内存地址,它们共用了一个数据,不管是修改a还是b,它们之间都会相互影响;
如果要实现深拷贝,就需要把a里面的数据重新开辟一块内存空间给b,让b在指向这个内存地址,让它们两个之间互相彼此独立即可
有两种简单的方式进行实现,展开运算符或for循环
let a=[1,2,3]
//1,使用展开运算符
//let b=[...a];
//2,使用for循环
let b=[]
for(let i=0;i
JSON.stringfy() 其实就是将一个 JavaScript 对象或值转换为 JSON 字符串,最后再用 JSON.parse() 的方法将JSON 字符串生成一个新的对象。一般情况下对普通对象需要进行深拷贝,可以使用这种方法进行深拷贝操作,这种是最简单且代码量最少的深拷贝方法
function deepClone(target) {
//创建JSON格式的字符串
let str = JSON.stringify(target);
//将JSON字符串转为JS数据
let data = JSON.parse(str);
return data;
}
缺点:
1,取不到值为 undefined 的 key;
2,如果对象里有函数,函数无法被拷贝下来;
3,对象直接转变为 date 字符串;
function deepclone(target){
let str = JSON.stringify(target)
let data = JSON.parse(str)
return data
}
let obj={
name:"张三",
age:18,
height:undefined,
date:new Date(),
arr:[1,2,3],
fun:function(){
console.log(this.name)
}
}
let deep1=deepclone(obj)
console.log(obj)
deep1.arr[2]=10
console.log(deep1)
当对象中只有一级属性,没有二级属性的时候,此方法可用。但是有二级属性的时候就会失效。
let obj={
name:"张三",
age:18,
height:undefined,
date:new Date(),
arr:[1,2,3,{weight:"180"}],
fun:function(){
console.log(this.name)
}
}
let result = Object.assign({},obj)
result.arr[0]=10
result.arr[3].weight="190"
console.log(obj)
console.log(result)
//实现数组或方法的深拷贝
let obj={
name:"张三",
age:18,
arr:[1,2,3],
sun:function(){
console.log(this.name+''+this.age)
}
}
function deepClone(Data){
if(typeof Data==='object'&&Data!==null){
let res = Array.isArray(Data)?[]:{};
for(let k in Data){
if(Data.hasOwnProperty(k)){
res[k]=deepClone(Data[k])
}
}
return res
}else{
return Data
}
}
let deep1=deepClone(obj)
deep1.name="李四"
deep1.arr[0]=10
deep1.sun=function () {
console.log(this.name)
}
deep1.sun()
console.log(deep1)
console.log(obj)
最终的返回结果,开辟了两块新的内容,彼此独立互不影响
总结:
1,浅拷贝的是地址指向,原对象修改的时候,新对象的数据也跟着修改,他们指向的是一个对象空间。 2,深拷贝:创建一个一模一样的对象,新对象跟原对象不共享内容(新对象和原对象各自独享内存),修改新对象不会改到原对象。
js中浅拷贝和深拷贝所涉及到的知识点和细节还有很多,这里只做了一个简单的整理。