Vue中如何避免对象引用关联,实现独立副本操作?
如何创建Vue ref对象的独立副本
这是因为JavaScript里对象属于引用类型,直接赋值myVariable = myObject.value只是把对象的内存地址传给了myVariable,两者指向同一个内存空间里的对象,所以修改一方的属性会同步影响另一方。要让myVariable成为独立副本,得根据对象的结构选择合适的拷贝方式:
1. 浅拷贝(适用于单层结构对象)
如果你的对象只有一层属性,没有嵌套的子对象,可以用扩展运算符或者Object.assign来做浅拷贝:
// 方法1:扩展运算符 myVariable = {...myObject.value} // 方法2:Object.assign myVariable = Object.assign({}, myObject.value)
⚠️ 注意:浅拷贝只会复制对象的第一层属性,如果对象里有嵌套的子对象,子对象还是引用类型,修改子对象的属性依然会影响原对象。
2. 深拷贝(适用于多层嵌套结构对象)
如果对象有多层嵌套,需要用深拷贝来彻底断开引用关系,常用的原生方法有两种:
方法A:JSON序列化/反序列化
通过JSON.parse(JSON.stringify())把对象转成JSON字符串再转回来,实现深拷贝:
myVariable = JSON.parse(JSON.stringify(myObject.value))
⚠️ 局限:这种方法无法处理函数、Symbol、undefined、循环引用这些特殊类型,遇到这些内容会丢失或报错。
方法B:structuredClone API
现代浏览器和Node.js都支持的原生API,能处理大部分类型(包括循环引用、Date、RegExp、Map/Set等),比JSON方法更强大:
myVariable = structuredClone(myObject.value)
3. 自定义深拷贝函数(处理特殊场景)
如果需要处理structuredClone也不支持的类型(比如函数),可以自己写递归的深拷贝函数:
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj if (obj instanceof Date) return new Date(obj.getTime()) if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags) // 处理数组或对象 const cloneObj = Array.isArray(obj) ? [] : {} for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key]) } } return cloneObj } // 使用 myVariable = deepClone(myObject.value)
选好拷贝方式后,修改myVariable的属性就不会影响myObject.value了。
内容的提问来源于stack exchange,提问作者gespinha
相关产品推荐
相关产品推荐

