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

在JavaScript/TypeScript中移除对象属性且保持原对象完整的实现方案

How to Remove (or Clear) Specific Properties from a Product Object & Nested Parts Without Altering the Original in TypeScript

The Problem

I have a TypeScript Product object with nested arrays, and I need to send it to an API but clear out the priceHistory and purchaseHistory properties (both on the top-level Product and each item in the parts array). Crucially, I don't want to modify the original object.

Here's my original Product structure:

const originalProduct = {
  productId: 1,
  productName: "ABC",
  orders: [{ orderId: 1, orderDate: "2020-01-01", amount: 100 }, { orderId: 2, orderDate: "2020-01-01", amount: 200 }],
  priceHistory: [{ date: "2020-01-1", price: 15 }, { date: "2020-02-1", price: 16 }],
  purchaseHistory: [{ purchaseDate: "2019-01-01", purchaseAmt: 10, qty: 20 }, { purchaseDate: "2019-02-01", purchaseAmt: 10, qty: 2 }],
  parts: [{ partId: 1, partName: "Part 1", priceHistory: [], orders: [], purchaseHistory: [] }, { partId: 2, partName: "Part 2", priceHistory: [], orders: [], purchaseHistory: [] }]
};

I want the resulting object to keep all other properties intact, but set priceHistory and purchaseHistory to empty arrays (both on the parent and nested parts).

My first attempt modified the original object because I was just assigning a reference:

// ❌ This modifies the original object!
let newProduct = originalProduct;
newProduct.priceHistory = [];
newProduct.purchaseHistory = []
newProduct.parts.forEach((part) => {
  part.priceHistory = [];
  part.purchaseHistory = [];
});

The Solution

The core issue with your initial code is that newProduct = originalProduct just copies a reference to the same object in memory. To avoid modifying the original, you need to create a deep enough copy of the object, then adjust the properties you want to clear.

Option 1: Manual Copy (Simple, for Known Structure)

If your object structure is fixed and not deeply nested beyond parts, you can use the spread operator (...) to create a shallow copy of the top-level object, then map over the parts array to create copies of each part:

// ✅ Creates a new object without modifying the original
const newProduct = {
  // Copy all top-level properties from the original
  ...originalProduct,
  // Override the properties we want to clear
  priceHistory: [],
  purchaseHistory: [],
  // Map over parts to create new copies of each part (clear their target properties)
  parts: originalProduct.parts.map(part => ({
    ...part,
    priceHistory: [],
    purchaseHistory: []
  }))
};

This works because:

  • The spread operator ...originalProduct creates a new top-level object (not a reference).
  • parts.map(...) returns a new array with new part objects (so we don't mutate the original parts array or its items).

Option 2: Reusable Function (For Dynamic/Deeply Nested Structures)

If you anticipate more nested properties or want a reusable solution, write a recursive function that clears specified properties across all nested objects:

/**
 * Creates a copy of an object (and nested objects/arrays) and clears specified properties to empty arrays
 * @param obj - The original object to copy
 * @param propsToClear - Array of property names to clear
 * @returns A new object with target properties cleared
 */
function cleanNestedObject<T extends object>(obj: T, propsToClear: string[]): T {
  // Create a shallow copy of the current object
  const cleanedObj = { ...obj };

  // Clear the target properties by setting them to empty arrays
  propsToClear.forEach(prop => {
    if (cleanedObj.hasOwnProperty(prop)) {
      cleanedObj[prop as keyof T] = [] as any;
    }
  });

  // Recursively process any nested arrays of objects
  for (const key in cleanedObj) {
    const value = cleanedObj[key];
    if (Array.isArray(value)) {
      cleanedObj[key] = value.map(item => 
        typeof item === 'object' && item !== null ? cleanNestedObject(item, propsToClear) : item
      ) as typeof value;
    }
  }

  return cleanedObj;
}

// Usage
const newProduct = cleanNestedObject(originalProduct, ['priceHistory', 'purchaseHistory']);

This function handles:

  • Top-level properties
  • Nested arrays of objects (like parts)
  • Any deeper nesting you might add later (e.g., if parts had their own nested objects with priceHistory)

Why Your Initial Code Failed

When you do let newProduct = originalProduct, you're not creating a new object—you're just pointing newProduct to the same object in memory as originalProduct. Any changes to newProduct (including modifying nested properties like parts) will directly affect the original object. Using the spread operator or a dedicated copy function breaks this reference link.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:37:43