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

TS/JS中如何深度克隆数组指定的对象属性

指定属性的对象深拷贝实现方案

针对仅拷贝指定属性、且做深度克隆的需求,有几种非常简便的实现方式,根据你的运行环境和项目依赖选择即可:


现代JS原生最简方案

目前所有现代浏览器、Node.js 17+ 都原生支持structuredClone()标准深拷贝API,配合数组reduce方法拾取指定属性,不需要额外引入任何依赖:

const sourceObj = { a: 1, b: 2, c: 3, nested: { val: 4 } }
const needCopyKeys = ["a", "b", "nested"]

const clonedResult = needCopyKeys.reduce((res, key) => {
  // 跳过源对象不存在的属性,避免结果里出现无意义的undefined
  if (Object.hasOwn(sourceObj, key)) {
    res[key] = structuredClone(sourceObj[key])
  }
  return res
}, {})

这个方案支持拷贝嵌套对象、数组、Date、RegExp等绝大多数常用数据类型,性能和兼容性都足够应对绝大多数业务场景。
注意:structuredClone无法拷贝函数、Symbol、DOM节点、Error实例这类特殊值,如果你的对象包含这类值,用下面的自定义递归方案更灵活。


兼容旧环境的轻量递归实现

如果需要兼容不支持structuredClone的老旧环境,可以自己写一个十几行的递归函数,同时完成属性拾取和深拷贝:

function deepPick(source, keys) {
  // 基础类型、null直接返回原值
  if (typeof source !== "object" || source === null) return source
  // 数组类型遍历每一项递归处理
  if (Array.isArray(source)) return source.map(item => deepPick(item, keys))
  // 对象类型仅拷贝指定属性
  return keys.reduce((res, key) => {
    if (Object.hasOwn(source, key)) {
      res[key] = deepPick(source[key], keys)
    }
    return res
  }, {})
}

// 调用示例
const sourceObj = { a: 1, b: 2, c: 3 }
const clonedResult = deepPick(sourceObj, ["a", "b"]) // 得到 {a:1, b:2}

你可以根据自己的业务需求修改这个函数的逻辑,比如支持嵌套路径属性拾取、自定义特殊类型的拷贝规则。


工具库快速实现

如果你的项目已经引入了Lodash这类通用工具库,不需要自己写逻辑,直接组合两个内置方法就能实现:

import { cloneDeep, pick } from "lodash"

const sourceObj = { a: 1, b: 2, c: 3 }
const clonedResult = cloneDeep(pick(sourceObj, ["a", "b"]))

避坑提醒:不要用对象展开运算符{...pick(source, keys)}或者Object.assign做拷贝,这两种都是浅拷贝,嵌套的对象/数组和原对象还是引用共享,修改会互相影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:01:06