js 深拷贝

132 阅读1分钟

1.JSON.parse(JSON.stringify())

    JSON.parse(JSON.stringify(obj))

利用JSON.parse实现深拷贝,可以书写快速方便,但是有以下情况不能使用

  1. 对象属性值是函数时不能拷贝
  2. 不能正确处理Date类型数据
  3. 不能处理RegExp
  4. 回忽略属性值是 undefined Symbol
  5. NaN会变成null

2. 手写递归复制拷贝

function deepCLone(obj, hash = new WeakMap()) {
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Date) return new Date(obj);
  if (obj === null || typeof obj !== 'object') return obj;
  if (hash.has(obj)) return hash.get(obj);

  let clone = new obj.constructor();
  // 如果obj时数组,那么obj.constructor 是[Function: Array]
  // 如果obj时对象,那么obj.constructor 是[Function: Object]
  hash.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 是否是自身的属性
      clone[key] = deepCLone(obj[key], hash);
    }
  }
  return clone;
}

3. MessageChannel通道实现深拷贝

function deppClone(obj) {
	return new Promise(resolve => {
		const { port1, port2 } = new MessageChannel()
		port1.postMessage(obj)
		port2.onmessage = e => {
			resolve(e.data)
		}
	})
}
const obj = { a: "", c: undefined, e: 0, f: [], g: NaN, h: null }

let newObj = null
await deppClone(obj).then(res => {
  newObj = res
})