JavaScript类实例拷贝共享数组引用导致DOM挂载异常问题
问题原因
你猜测的共享数组引用是核心问题,具体可拆解为两层错误:
- 浅拷贝导致引用类型属性共享
Object.assign执行的是浅拷贝,当拷贝的源对象上有数组、普通对象、DOM节点这类引用类型的属性时,只会拷贝对应的内存地址,不会完整克隆属性值本身。你当前的CoppyComponent逻辑直接把hi实例上arr数组的内存地址复制给了h1Copy,所以两个实例操作的是同一个数组里存储的DOM元素。 - DOM节点的挂载特性限制
同一个DOM节点不能同时挂载到两个父节点下,调用h1Copy.load(".b")时,会把数组里存的原有DOM节点直接从父节点.a移动到新的父节点.b,因此最终元素仅显示在.b容器中。
另外注意你现有代码存在两处拼写错误:关键字Class需要改为小写class,Object.assgin需要改为Object.assign,否则会直接触发语法报错。
解决方案
需要修改拷贝逻辑,用深拷贝替换原有浅拷贝逻辑,同时对DOM节点做单独克隆处理,避免共享引用:
class CopyComponent { constructor(element) { // 自定义深拷贝逻辑,适配DOM节点克隆需求 const deepClone = (target) => { if (target === null || typeof target !== 'object') return target; // 单独处理数组类型 if (target instanceof Array) return target.map(item => deepClone(item)); // 单独处理DOM节点,深克隆节点包括子元素 if (target instanceof HTMLElement) return target.cloneNode(true); // 保持原型链继承 const clonedObj = Object.create(Object.getPrototypeOf(target)); for (let key in target) { if (target.hasOwnProperty(key)) { clonedObj[key] = deepClone(target[key]); } } return clonedObj; } return deepClone(element); } }
修改后h1Copy上的arr数组是全新的独立数组,里面存储的也是克隆后的新DOM节点,调用h1Copy.load(".b")时只会操作新DOM节点,不会影响原实例hi挂载在.a下的元素,即可实现两个容器分别挂载对应元素的需求。
内容的提问来源于stack exchange,提问作者Adi Adi
相关产品推荐
相关产品推荐

