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

Angular中JSON对象深拷贝后副本同步变更的问题及解决方法

解决Angular组件深拷贝后原对象修改导致副本同步变化的问题

问题原因分析

你遇到的问题大概率是以下两种情况之一:

  • 拷贝时机不对:如果父组件的cityinfoJSON是异步加载(比如从接口请求),ngOnInit只会执行一次,此时可能cityinfoJSON还未被赋值,后续父组件传入真实数据时,子组件没有重新执行深拷贝,导致originalJSON最终指向的还是父组件的原对象引用。
  • JSON序列化拷贝的局限性:JSON.parse(JSON.stringify())无法处理特殊类型(如Date、函数、Symbol、循环引用),遇到这些类型时会丢失数据或无法完成深拷贝,导致副本和原对象仍存在引用关联。

解决方案

1. 监听输入属性变化,确保拷贝时机正确

改用ngOnChanges钩子监听cityinfoJSON的变化,每次输入属性更新时重新执行深拷贝:

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html'
})
export class YourComponent implements OnChanges {
  @Input() cityinfoJSON: any;
  originalJSON: any;

  ngOnChanges(changes: SimpleChanges): void {
    // 仅当cityinfoJSON有值且发生变化时执行拷贝
    if (changes['cityinfoJSON'] && changes['cityinfoJSON'].currentValue) {
      this.originalJSON = JSON.parse(JSON.stringify(changes['cityinfoJSON'].currentValue));
    }
  }
}

2. 替换为递归深拷贝(处理特殊类型场景)

如果cityinfoJSON包含JSON序列化无法处理的类型,自己实现递归深拷贝函数:

// 组件内添加递归深拷贝方法
deepClone(obj: any): any {
  // 基本类型直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 处理数组
  if (Array.isArray(obj)) {
    return obj.map(item => this.deepClone(item));
  }

  // 处理普通对象
  const clonedObj = {} as Record<string, any>;
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clonedObj[key] = this.deepClone(obj[key]);
    }
  }
  return clonedObj;
}

// 使用深拷贝方法
this.originalJSON = this.deepClone(this.cityinfoJSON);

3. 检查修改逻辑,确保操作的是原对象

确认代码中修改的是cityinfoJSON而非originalJSON,比如:

// 正确:修改原对象
this.cityinfoJSON.countyPlaceVerified = 'Y';

// 错误:不小心修改了副本
// this.originalJSON.countyPlaceVerified = 'Y';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:45:04