本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在js中,数据类型分两种:
基本数据类型和引用数据类型
基本类型数据存在于 栈内存 中,引用数据类型的属性存在于栈内存中,值存在堆内存中,通过指针来指向对应值
浅拷贝
拷贝出来的变量 copyArray,只是拷贝指针,指向的还是同一个堆内存中的数据,所以,其中一个值改变,另外一个值相应改变
深拷贝
拷贝出来的值,在堆内存中另外开辟空间,存储新值,通过指针指向。当改变新拷贝的值时,原值不会被改变。
实现深拷贝的四种方式
举个栗子
var obj = { name: '小甜甜', age: 24, say() { console.log('bebebeautiful'); } }
使用JSON.parse(JSON.stringify(obj))
通过json实现 属性可以深拷贝 但是会造成
方法丢失
console.log(JSON.parse(JSON.stringify(obj))) // { name: '小甜甜', age: 24}
通过for-in遍历循环
var obj1 = {};
for (var attr in obj) {
obj1[attr] = obj[attr]
}
console.log(obj1); // { name: '小甜甜', age: 24, say() { console.log('bebebeautiful'); } }
console.log(obj); // { name: '小甜甜', age: 24, say() { console.log('bebebeautiful'); } }
/**
* 此时的obj1 和obj 他们看着数据都是一样的,但是在内存中他们的物理地址却不相同,相互独立纯在的,修改了彼此却不会干预到对方
*/
使用Object.assign()实现
var obj1 = {};
Object.assign(obj1, obj);
// 这是将obj合并到obj1上
console.log(obj1);// { name: '小甜甜', age: 24, say() { console.log('bebebeautiful'); } }
obj1.age = 66; //obj感受不到变化
console.log(obj);// { name: '小甜甜', age: 24, say() { console.log('bebebeautiful'); } }
用扩展运算符...实现对象的深拷贝
//...叫做扩展运算符 ES6新增
// 使用场景 在函数调用 或数组构造时,将数组表达式或者string在语法层面展开
var obj = { name: 'xtt', age: 18 };
var obj1 = { ...obj };
obj1.age = 66; //改变obj1,不影响obj
// console.log(obj);