JavaScript自定义深拷贝后对象内的数组是否会被转为普通对象?
结论先行
newObj.marks是原型指向数组的普通对象,不是真正的数组实例,所以Array.isArray()返回false。
具体原因
- 你的
cloneObject方法的克隆逻辑存在缺陷
你用Object.create(obj)生成克隆对象,当传入的obj是数组时:
Object.create(数组)会生成一个普通对象,将这个普通对象的隐式原型__proto__指向原数组,但它本身不具备数组的内部[[ArrayLength]]等专属插槽,不是Array的直接实例。Array.isArray()的判断规则是检测对象的内部标签是否为Array,只有真正的数组实例才会返回true,你生成的这个对象不符合要求,所以返回false。
- 控制台显示为Array的原因
浏览器/Node的控制台在打印对象时,会展示该对象的原型链最顶层的构造函数名称,因为这个对象的原型链上存在Array.prototype,所以控制台会标注为Array,只是展示方便,不代表它本身是数组实例。
修复方案
调整你的深克隆逻辑,单独处理数组类型:
function cloneObject(obj) { // 基本类型直接返回 if (obj === null || typeof obj !== 'object') { return obj } // 单独处理数组 if (Array.isArray(obj)) { const clone = [] for (const key in obj) { clone[key] = cloneObject(obj[key]) } return clone } // 处理普通对象 const clone = Object.create(obj) for (const key in obj) { clone[key] = cloneObject(obj[key]) } return clone }
修改后克隆得到的newObj.marks就是标准数组,Array.isArray()会正确返回true。
内容的提问来源于stack exchange,提问作者Nithyashree B L
相关产品推荐
相关产品推荐

