JavaScript对象深拷贝的边界失效场景问询(不使用Lodash)
你的深拷贝实现的边界失效场景
以下是你的代码会失效的核心场景:
- 嵌套层级的函数丢失:你只处理了顶层对象的函数(比如示例里的
e),如果对象的嵌套子属性里有函数(比如Obj.b.c.i = () => '嵌套函数'),JSON.stringify会直接忽略这个嵌套函数,后续的循环只遍历顶层key,不会递归处理嵌套结构,最终拷贝结果会丢失这个嵌套函数。 - 非Date的特殊对象类型失效:除了
Date,像RegExp、Map、Set、Promise以及自定义类实例这类特殊类型,都会被JSON.stringify错误处理:RegExp会被转成空对象{},且你的代码不会修复这个问题,拷贝后正则直接失效;Map/Set会被转成空对象,所有存储的数据全部丢失;- 自定义类实例(比如
class User { constructor(name) { this.name = name } })会被转成普通对象,丢失原型链,拷贝后的对象不再是原类的实例。
- 循环引用直接报错:如果对象存在循环引用(比如
Obj.self = Obj),JSON.stringify会直接抛出Converting circular structure to JSON错误,整个拷贝流程直接失败。 - 嵌套层级的undefined丢失:如果嵌套对象里有值为
undefined的属性(比如Obj.b.c.j = undefined),JSON.stringify会忽略这个属性,后续循环不会遍历嵌套结构,导致拷贝后的对象里没有这个属性,和原对象不一致。 - 特殊数值被篡改:
NaN、Infinity这类特殊数值,会被JSON.stringify转成null,你的代码没有处理这类情况,拷贝后数值会变成null,和原对象不符。 - 数组内的特殊元素异常:如果数组里包含函数、
undefined、NaN这类元素(比如Obj.g = [1, () => 2, undefined, NaN]),JSON.stringify会移除函数和undefined,把NaN转成null,而你的代码不会遍历数组元素进行修复,最终拷贝后的数组内容和原数组差异极大。 - Symbol键属性丢失:
JSON.stringify会忽略以Symbol作为键的属性,同时for...in循环也不会遍历Symbol类型的键,导致拷贝后的对象完全丢失所有Symbol键对应的属性。
内容的提问来源于stack exchange,提问作者era s'q
相关产品推荐
相关产品推荐

