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

如何克隆ES6导入的数据以创建独立可变对象?

Cypress测试中深拷贝数据集的最优方案?

我在Cypress测试中需要两组略有差异的数据集。由于数据集较长且与原数据的差异极小,原本打算复制对象并按需修改,但ES6导入的变量是绑定关系,修改副本会同时改动原对象。

问题演示

测试数据文件(test.json)

{
  "foo": {
     "bar": "XXX"
  }
}

浅拷贝导致的问题

import test from './test.json'

const firstTest = {...test}
const secondTest = {...test}

secondTest.foo.bar = '@@@'

console.log(firstTest.foo.bar)
// 输出: @@@

扩展运算符(...)和Object.assign()都只能实现浅拷贝,对于嵌套对象,内部的引用还是共享的,所以修改嵌套属性会影响所有副本。

当前可行的深拷贝方法

import test from './test.json'

const firstTest = JSON.parse(JSON.stringify(test))
const secondTest = JSON.parse(JSON.stringify(test))

secondTest.foo.bar = '@@@'

console.log(firstTest.foo.bar)
// 输出: XXX

更优的深拷贝方案

1. 使用原生structuredClone() API

现代浏览器原生支持的深拷贝方法,比JSON序列化更可靠,能处理Date、RegExp等特殊类型,且无需额外依赖:

import test from './test.json'

const firstTest = structuredClone(test)
const secondTest = structuredClone(test)

secondTest.foo.bar = '@@@'
console.log(firstTest.foo.bar) // 输出: XXX

Cypress运行在浏览器环境,完全兼容该API。

2. 自定义递归深拷贝函数

如果需要自定义拷贝逻辑(比如跳过特定属性、处理特殊类型),可以手动实现递归拷贝:

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj
  // 处理Date对象
  if (obj instanceof Date) return new Date(obj.getTime())
  // 处理RegExp对象
  if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags)
  // 处理数组
  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
}

// 使用示例
import test from './test.json'
const firstTest = deepClone(test)
const secondTest = deepClone(test)

3. 利用Cypress Fixture特性

如果数据集是作为fixture使用,每次调用cy.fixture()都会返回独立的深拷贝对象,天然避免引用共享问题:

cy.fixture('test.json').then(test => {
  const firstTest = test
  firstTest.foo.bar = 'YYY'
  // 此处修改不会影响后续的fixture调用
})

cy.fixture('test.json').then(test => {
  console.log(test.foo.bar) // 输出: XXX
})

为什么JSON序列化不是最优解?

JSON.parse(JSON.stringify())存在明显局限性:

  • 会忽略undefined、function、Symbol类型的属性
  • 丢失Date对象的类型,转成字符串后无法自动还原
  • 遇到循环引用的对象会直接抛出错误

内容的提问来源于stack exchange,提问作者Hexodus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:50:28