You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:43:45