使用JSON序列化克隆数组时method属性丢失,如何保留方法?
问题原因
你遇到的问题本质是**JSON.stringify不支持序列化函数类型**——JSON格式只包含字符串、数字、布尔值、数组、普通对象和null,函数、undefined、Symbol这些类型都会被直接忽略掉,所以用JSON.parse(JSON.stringify(...))克隆时,method属性自然就丢失了。
解决方案
根据你的需求(创建新数组,同时保留函数),可以选择以下几种方式:
1. 浅克隆(适合层级较浅的场景)
如果你的数据结构层级不深,只需要创建新的数组和外层对象,不需要完全深拷贝内部嵌套对象,可以用ES6的展开运算符来实现:
const visitorItem = this.visitorsTemplate.map(item => ({ ...item, // 克隆外层对象 children: item.children.map(child => ({...child})) // 克隆children数组里的每个子对象 }))
这种方式会创建新的数组和对象实例,同时保留method函数的引用,因为函数是引用类型,这里只是复制了它的引用,不会丢失。
2. 自定义深克隆函数(需要完全独立的深拷贝)
如果你的数据有更深的嵌套结构,需要完全克隆所有层级的对象,同时保留函数,可以自己实现一个递归克隆函数:
export const deepClone = (obj) => { // 非对象类型直接返回(包括函数、原始类型) if (obj === null || typeof obj !== 'object') { return obj; } // 处理数组 if (Array.isArray(obj)) { return obj.map(item => deepClone(item)); } // 处理普通对象 const clonedObj = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; }
然后用这个函数替换原来的clone:
console.log(this.visitorsTemplate) const visitorItem = deepClone(this.visitorsTemplate) console.log(visitorItem)
这个函数会递归克隆所有层级的对象和数组,同时保留函数、Symbol等JSON不支持的类型。
3. 使用成熟的工具库(可选)
如果你不想自己写克隆逻辑,可以用像Lodash的_.cloneDeep方法,它原生支持克隆函数、Symbol等特殊类型:
import _ from 'lodash'; const visitorItem = _.cloneDeep(this.visitorsTemplate);
不过这种方式需要引入第三方库,适合已经在项目中使用Lodash的场景。
注意事项
- 函数是引用类型,不管用哪种克隆方式,克隆后的
method和原对象的method指向同一个函数实例。如果你需要完全独立的函数(比如修改其中一个不影响另一个),可以通过new Function或者函数toString的方式重新创建,但这种场景非常少见,一般保留引用就足够了。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

