JaveScript数据类型存储
- 简单类型:栈存储;
- 引用类型:堆存储,引用类型的变量是一个指向堆内存中的一个指针,将指针保存在栈内存中;
浅拷贝
定义
浅拷贝创建一个新对象,仅复制对象的第一层属性。
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
实现方式
- 扩展运算符(...)
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
2.Object.assign():
const shallowCopy = Object.assign({}, obj);
注意
修改改原对象的引用类型属性会影响到拷贝后的对象:
obj.b.c = 99;
console.log(shallowCopy.b.c); // 输出 99
深拷贝
深拷贝创建一个新对象,并递归复制所有层级的属性,新旧对象完全独立,不共享任何引用。
实现方法:
-
JSON.parse(JSON.stringify(obj))
:const obj = { a: 1, b: { c: 2 } }; const deepCopy = JSON.parse(JSON.stringify(obj));
缺点:
- 无法处理
函数
、Symbol
、undefined
。 - 会丢失
Date
对象(转为字符串)。 - 无法处理循环引用(如
obj.self = obj
会报错)。
- 无法处理
-
递归实现:
手动实现深拷贝,处理多种数据类型:function deepClone(source, map = new WeakMap()) { // 简单类型直接返回 if (source === null || typeof source !== 'object') return source; if (map.has(source)) return map.get(source); // 解决循环引用 const target = Array.isArray(source) ? [] : {}; map.set(source, target); for (const key in source) { if (source.hasOwnProperty(key)) { target[key] = deepClone(source[key], map); } } return target; }
-
第三方库:
-
Lodash的
_.cloneDeep()
:const _ = require('lodash'); const deepCopy = _.cloneDeep(obj);
-
特点:
-
完全独立的对象,修改原对象的任何属性不会影响拷贝后的对象:
obj.b.c = 99; console.log(deepCopy.b.c); // 输出 2
总结:讲一讲深拷贝和浅拷贝的区别
如果拷贝的类型为引用类型,浅拷贝只会复制一层,如果属性值依旧是一个引用类型,则会共享同一个引用地址,表现为修改改原对象的引用类型属性会影响到拷贝后的对象。深拷贝会递归复制所有层级的属性,完全断开引用关系,生成一个完全独立的新对象,修改任何一方都不会影响另一方。