# 深拷贝

模拟实现一个深拷贝,并考虑对象相互引用以及 Symbol 拷贝的情况

利用一个WeakMap来破解相互引用

利用Object.getOwnPropertySymbols来获取Symbol键值

function deepClone(target, hash = new WeakMap()) {
	// 已经遍历过了就返回
	if (hash.has(target)) return target
	let cobj
  // 处理为null的特殊情况
	if (target === null) {
		return target
	}
  // 如果是基本数据类型 则直接返回了
	const t = typeof target
	switch (t) {
		case 'string':
		case 'number':
		case 'boolean':
		case 'undefined':
		case 'symbol':
			return target
	}
	if (Array.isArray(target)) {
    hash.set(target, true);
		cobj = []
		target.forEach((o) => {
			cobj.push(deepClone(o, hash))
		})
	} else {
		cobj = {}
		if (Object.prototype.toString.call(target) === '[object Object]') {
			hash.set(target, true)
			// 同时考虑string key 和 symbol key
			const keys = [...Object.getOwnPropertyNames(target), ...Object.getOwnPropertySymbols(target)]
			for (let i = 0, len = keys.length; i < len; i++) {
				const key = keys[i]
				cobj[key] = deepClone(target[key], hash)
			}
		} else {
      // 考虑到可能是函数等的情况
			cobj = target
		}
	}
	return cobj
}
const source = {
	a: 1,
	b: 'string',
	c: Symbol('foo'),
	d: undefined,
	e: null,
	f: function () {},
	h: new Date(),
	arr: [{ d: 'd' }, 22, 44],
	obj: {
		x: 1
	}
}
source.mySelf = source
let symbol2 = Symbol('bar')
source[symbol2] = 'xdyuan'
const ret = deepClone(source)
上次更新: 4/1/2025, 9:33:10 AM