原型对象不可深拷贝,需深拷贝的是其实例对象;三类情形:一、纯数据用 json 法;二、需保留原型链用 object.create + 递归深拷贝自有属性;三、复杂类型用 structuredclone 或增强递归函数。

直接说重点:原型对象本身不能也不该被“深拷贝”来防止干扰;真正要处理的是基于原型创建的实例对象,且需确保拷贝不破坏原型链、不丢失方法、不共享可变嵌套数据。
JavaScript 中的原型(prototype)是用于共享方法和属性的机制,它本身不是数据容器。你不需要、也不应该对 Function.prototype 或某个构造函数的 prototype 对象做深拷贝。真正需要深拷贝的,是从该原型派生出来的具体实例对象——比如 new Person() 得到的对象。
下面分三类情况讲清楚怎么做:
一、普通实例对象(无函数/Date/循环引用)→ 用 JSON 法最简
适用场景:接口返回的纯数据对象(如 {user: {name: "张三", tags: ["admin"]}}),不含方法、日期、正则等。
操作方式:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 调用
JSON.parse(JSON.stringify(obj)) - 拷贝后对象与原对象完全隔离,修改嵌套数组或子对象不会影响原对象
-
注意:拷贝结果是 plain object,不继承原对象的原型(即
copied instanceof Person === false)
二、需保留原型链和方法 → 用 Object.create + 属性遍历
如果你希望拷贝后的对象仍属于同一类型(如仍是 Person 实例),并能调用原型上的方法(如 person.sayHello()),就不能丢掉原型链。
做法是:先用 Object.create(原对象.constructor.prototype) 创建新对象,再把可枚举自有属性深拷贝过去:
- 对每个属性判断类型:基本值直接赋值,对象/数组递归深拷贝
- 跳过不可枚举属性、Symbol 键、原型方法(它们本就该共享)
- 这样新对象既保持了类型身份,又隔离了数据层
三、复杂对象(含 Date、Map、Set、循环引用、函数)→ 用 structuredClone 或递归增强版
现代浏览器(Chrome 98+、Firefox 94+、Safari 15.4+)已支持原生 structuredClone():
- 支持
Date、RegExp、Map、Set、ArrayBuffer等,且自动处理循环引用 - 但仍不复制函数、undefined、Symbol、Error 对象
- 返回对象的原型链会被重置为默认(
Object.prototype),所以不适用于需保留自定义原型的场景
若必须保留原型 + 支持所有类型,就得手写增强递归函数,配合 WeakMap 记录已拷贝对象防循环引用,并对特殊类型单独处理(如 new Date(obj.getTime()))。
不复杂但容易忽略。










