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

TypeScript中如何正确复制数组并修改元素且不影响原数组?

问题原因

你之前用的几种复制方式都是浅拷贝:虽然复制了外层数组和每个Span对象,但对象里的tags数组是引用类型,拷贝后新对象的tags和原对象的tags指向同一个内存地址。所以你修改copy[splitIndex].tags时,原props.value里对应的tags也会跟着变。

解决方案

需要对每个对象的tags数组也做一层拷贝,实现深拷贝到tags层级。修改复制数组的代码即可:

// 正确的拷贝方式:同时复制tags数组
let copy = props.value.map(a => ({
  ...a,
  tags: [...a.tags] // 用扩展运算符复制tags数组,也可以用a.tags.slice()或Array.from(a.tags)
}))
修改后的完整代码
type Span = {
  start: number
  end: number
}

// 补充包含tags的类型,避免使用as any
type SpanWithTags = Span & {
  tags: string[]
}

const handleSplitClick = (span: Span, tag: string) => {
    // 拷贝外层数组+每个对象,同时复制tags数组
    let copy = props.value.map((a: SpanWithTags) => ({
      ...a,
      tags: [...a.tags]
    }))
    const splitIndex = copy.findIndex(s => s.start === span.start && s.end === span.end)
    if (splitIndex !== -1 ){
      const targetSpan = copy[splitIndex]
      const tagIndex = targetSpan.tags.findIndex(t => t === tag)

      if (tagIndex > -1){
        targetSpan.tags.splice(tagIndex, 1)
        console.log(copy) // 修改的是新数组的tags
        console.log(props.value) // 原数组的tags不受影响
      }
    }
 }
额外说明
  • 如果你的Span对象还有更深层次的嵌套引用(比如tags里还有对象),那需要进一步深拷贝,但从场景看,tags是字符串数组,只需要拷贝这一层就够了。
  • 尽量避免用as any,通过定义SpanWithTags类型可以让代码更安全,减少类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:15:20