[JS]深浅拷贝的相关骚操作包含四种实现深拷贝方案

178 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

在js中,数据类型分两种: 基本数据类型引用数据类型

  • 基本类型数据 存在于 栈内存 中,
  • 引用数据类型 的属性存在于栈内存中,值存在堆内存中,通过指针来指向对应值

浅拷贝

拷贝出来的变量 copyArray,只是拷贝指针,指向的还是同一个堆内存中的数据,所以,其中一个值改变,另外一个值相应改变

image.png

深拷贝

拷贝出来的值,在堆内存中另外开辟空间,存储新值,通过指针指向。当改变新拷贝的值时,原值不会被改变。

image.png

实现深拷贝的四种方式

举个栗子

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);