javascript深拷贝和浅拷贝

    0

浅拷贝

lodash.clone

js
var _ = require('lodash'); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3]}; var obj2 = _.clone(obj1);console.log(obj1.b.f === obj2.b.f);// true

...运算符

Object.assign

Array.prototype.concat()

Array.prototype.slice()

深拷贝

JSON.parse(JSON.stringify())

缺点:只适用JSON安全的对象

  • 循环引用无法拷贝,BigInt报错
  • 丢失对象的constructor
  • Infinity和-Infinity为null
  • 只能序列化对象的可枚举属性
  • 正则,函数,undefined
  • Symbol、undefined,Function会丢失,
  • 正则、Error,Map、Set变空对象
  • NAN会变null
  • 日期 Date 对象变字符串
js
const test = { name: "test"}; const data = { a: "123", b: 123, c: true, d: [43, 2], e: undefined, f: null, g: function() { console.log("g"); }, h: new Set([3, 2, null]), i: Symbol("fsd"), j: test, k: new Map([ ["name", "张三"], ["title", "Author"] ]), l: NaN, m: new RegExp(".*?"), n: new Date() }; console.log(JSON.parse(JSON.stringify(data)))

1615270182505BbMqiS

lodash.cloneDeep

js
const _ = require('lodash'); const obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3]}; const obj2 = _.cloneDeep(obj1);console.log(obj1.b.f === obj2.b.f);

MessageChannel

  1. 如果需要拷贝的对象没有函数,可以使用MessageChannel实现
js
function deepClone(val) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel() port2.onmessage = e => resolve(e.data) port1.postMessage(val) }) }

递归实现

  1. 首先实现一个最简单的深拷贝
js
function deepClone(target) { let cloneTarget = {}; const keys=Object.keys(target) for (const key of keys) { cloneTarget[key] = target[key]; } return cloneTarget; };
  1. 如果是原始类型直接返回,引用类型,递归拷贝
javascript
function deepClone(target) { if(typeof target==='object'){ let cloneTarget = Array.isArray(target) ? [] : {}; const keys = Object.keys(target) for (const key of keys) { cloneTarget[key] = deepClone(target[key]); } return cloneTarget; }else { return target } };
  1. 解决循环引用
javascript
function deepClone(target,map = new Map()) { if(typeof target==='object'){ let cloneTarget = Array.isArray(target) ? [] : {}; if (map.has(target)) { return target; } map.set(target, cloneTarget); const keys = Object.keys(target) for (const key of keys) { cloneTarget[key] = deepClone(target[key],map); } return cloneTarget; }else { return target } };
  1. 进一步完善

单独处理各个数据类型 funtion map set 等等

js
function deepClone(target, map = new WeakMap()) { if (typeof target === 'object') { if (target === null) {//null return null } if(target instanceof Date){ return target } let cloneTarget = Array.isArray(target) ? [] : {}; if (map.has(target)) { return target; } map.set(target, cloneTarget); const keys = Object.keys(target) for (const key of keys) { cloneTarget[key] = deepClone(target[key], map); } return cloneTarget; } else { return target } }

Proxy

//todo

评论区
共有评论 0
暂无评论