在JavaScript中,实现深拷贝可以通过递归地复制所有层级的属性来完成。它创建一个新的对象,将一个对象从内存中完整地拷贝出来一份给该新对象,并从堆内存中开辟一个全新的空间存放新对象,且新对象的修改并不会改变原对象,二者实现真正的分离。
使深拷贝函数可以确保你得到一个与原始对象完全独立的副本,不论原始对象的内部结构有多复杂。
function deepClone(target) {
	const map = new WeakMap()
	function isObject(target) {
		return (typeof target === 'object' && target) || typeof target === 'function'
	}
	function clone(data) {
		if (!isObject(data)) {
			return data
		}
		if ([Date, RegExp].includes(data.constructor)) {
			return new data.constructor(data)
		}
		if (typeof data === 'function') {
			return new Function('return ' + data.toString())()
		}
		const exist = map.get(data)
		if (exist) {
			return exist
		}
		if (data instanceof Map) {
			const result = new Map()
			map.set(data, result)
			data.forEach((val, key) => {
				if (isObject(val)) {
					result.set(key, clone(val))
				} else {
					result.set(key, val)
				}
			})
			return result
		}
		if (data instanceof Set) {
			const result = new Set()
			map.set(data, result)
			data.forEach(val => {
				if (isObject(val)) {
					result.add(clone(val))
				} else {
					result.add(val)
				}
			})
			return result
		}
		const keys = Reflect.ownKeys(data)
		const allDesc = Object.getOwnPropertyDescriptors(data)
		const result = Object.create(Object.getPrototypeOf(data), allDesc)
		map.set(data, result)
		keys.forEach(key => {
			const val = data[key]
			if (isObject(val)) {
				result[key] = clone(val)
			} else {
				result[key] = val
			}
		})
		return result
	}
	return clone(target)
}示例使用:
var original = { a: 1, b: { c: 2 },e:()=>{console.log('hello')} };
var clone = deepClone(original);
console.log(clone === original); // 输出: false
console.log(clone.b === original.b); // 输出: false基本类型数据
键和值都是基本类型的普通对象
Symbol作为对象的key
Date和RegExp对象类型
Map和Set对象类型
Function对象类型(函数我们一般不用深拷贝)
对象的原型
不可枚举属性
循环引用
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!