? 浅拷贝
只是拷贝了基本类型的数据, 而引用类型数据, 复制后也是会发生引用, 我们把这种拷贝叫做浅拷贝 (浅复制)
对象浅拷贝:
- var obj1 = { a: 10, b: 20, c: 30 };
- var obj2 = obj1;
- obj2.b = 100;
- console.log(obj1);
- // { a: 10, b: 100, c: 30 } <-- b 被改到了
- console.log(obj2);
- // { a: 10, b: 100, c: 30 }
数组浅拷贝:
- var arr = ["One","Two","Three"];
- var arrto = arr;
- arrto[1] = "test";
- console.log("数组的原始值:" + arr + "");// 数组的原始值: One,test,Three
- console.log("数组的新值:" + arrto + "");// 数组的新值: One,test,Three
- ?
深拷贝
深拷贝: 在计算机中开辟了一块新的内存地址用于存放复制的对象.(对属性中所有引用类型的值, 遍历到是基本类型的值为止.?)
对象的深拷贝
方式一: 简单的对象 (不算是真正的深拷贝)
- var a = {name:'1',age:'2',color:'3'};
- function copyObj(a) {
- var b = {};
- for(var key in a) {
- b[key] = a[key];
- }
- return b;
- }
- var c = copyObj(a);
- c.name = '5';
- console.log('c',c);
- console.log('a',a);
方式二: ES6? let {...b} = a;?
方式三: 复杂对象, 利用递归来实现深拷贝 (最常用的)
- function cloneObject (obj) {
- var newObj = {} // 如果不是引用类型, 直接返回
- if (typeof (obj) !== 'object') {
- return obj
- }
- // 如果是引用类型, 遍历属性
- else{
- for (var attr in obj) {
- // 如果某个属性还是引用类型, 递归调用
- newObj[attr] = cloneObject(obj[attr])
- }
- }
- return newObj
- }
我们先判断它是否为引用类型, 如果不是, 直接返回?
如果是, 循环遍历该对象的属性, 如果某个属性还是引用类型, 则针对该属性再次调用 cloneObject 函数?
方式四: 用 JSON.stringify 把对象转成字符串, 再用 JSON.parse 把字符串转成新的对象.(最常用的)
- var obj1 = { body: { a: 10 } };
- var obj2 = JSON.parse(JSON.stringify(obj1));
- obj2.body.a = 20;
- console.log(obj1);
- // { body: { a: 10 } } <-- 沒被改到
- console.log(obj2);
- // { body: { a: 20 } }
- console.log(obj1 === obj2);
- // false
- console.log(obj1.body === obj2.body);
- // false
数组深拷贝
ES5:slice() 和 concat()
- var a = [1,2,3];
- var b = a.slice(0);
- var c = a.concat();
- b.push(4);
- c.push(5);
- a; //[1,2,3]
- b; //[1,2,3,4]
- c; //[1,2,3,5]
- ES6:let [...b] = a;
来源: https://www.2cto.com/kf/201807/763789.html