深浅拷贝的区别
深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。
假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
浅拷贝例子:
// 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用. var obj = { id:1, name:'ww' } var co = {} for (const k in obj) { co[k] = obj[key]; } // 拷贝的是地址,和原来的数据指向同一个地址
如果 obj 的层级再深点,如
var obj = { id:1, name:'ww', msg:{ age:19 }, }
此时 更改拷贝后的元素值,被拷贝的值也会发生变化
es6中实现浅拷贝的方法:
Object.assign( target .. sources)
深拷贝例子:
// 深拷贝拷贝多层,每一级别的数据都会拷贝. var obj = { id:1, name:'ww', msg:{ age:19 }, color:['red','green'] } var co = {}; function deepCopy(newobj,oldobj){ for (var k in oldobj) { // 判断属性值属于哪种数据类型 // 1.获取属性值 oldobj[k] var item = oldobj[k]; // 2.判断这个值是否是数组 这里之所以把Array判断放在前面是因为,Array也是Object if (item instanceof Array) { newobj[k] = []; deepCopy(newobj[k],item); }else if (item instanceof Object) { // 3.判断这个值是否是对象 newobj[k] = {}; deepCopy(newobj[k],item); }else { // 4.属于简单简单类型 newobj[k] = item; } } } deepCopy(co,obj); // 更改拷贝后的值 co.msg.age = 25; console.log('co',co); console.log('obj',obj);
深拷贝的另一种实现:
var temp = JSON.parse(JSON.stringify(obj))
javascript值传递与址传递
基本类型与引用类型最大的区别实际就是传值与传址的区别
值传递:基本类型采用的是值传递。
址传递:引用类型则是地址传递,将存放在栈内存中的地址赋值给接收的变量。
分析:由于a和b都是引用类型,采用的是址传递,即a将地址传递给b,那么a和b必然指向同一个地址(引用类型的地址存放在栈内存中),而这个地址都指向了堆内存中引用类型的值。当b改变了这个值的同时,因为a的地址也指向了这个值,故a的值也跟着变化。
就好比是a租了一间房,将房间的地址给了b,b通过地址找到了房间,那么b对房间做的任何改变(添加了一些绿色植物)对a来说肯定同样是可见的。
那么如何解决上面出现的问题,就是使用浅拷贝或者深拷贝了。
链接:知乎