原型式继承默认不等于浅拷贝,因为Object.create(parent)仅设置__proto__指向父对象,属性访问走原型链,不复制任何属性;浅拷贝需显式调用Object.assign、展开运算符等手动实现。

原型式继承中“浅拷贝父对象属性”不是标准继承目的,而是一种手动模拟行为——它绕过原型链查找机制,直接把父对象的自有属性复制到子对象上。这种做法本质是属性赋值,不建立原型连接,也不支持方法复用或动态更新,但能快速获得一份第一层独立的数据副本。
为什么原型式继承默认不等于浅拷贝
JavaScript 原型式继承(如 Object.create(parent))只是让新对象的 __proto__ 指向父对象,所有属性访问都走原型链。父对象的引用类型属性(如数组、嵌套对象)仍被所有子对象共享——这不是拷贝,是委托。
所谓“浅拷贝父对象属性”,必须显式执行复制动作,常见方式有:
-
Object.assign({}, parent):只复制可枚举的自有属性 -
{...parent}(展开运算符):同上,语法更简洁 -
for...in循环 +hasOwnProperty判断:可控制是否包含非枚举属性
浅拷贝后属性修改的影响范围
复制后,子对象与父对象在第一层属性上完全分离:
立即学习“Java免费学习笔记(深入)”;
- 基本类型(string/number/boolean):各自独立,互不影响
- 引用类型(object/array/function):仍共享同一份内存地址,改子对象里的
arr[0]或obj.name,父对象对应字段也会变
例如:
const parent = { name: 'A', list: [1, 2] };const child = Object.assign({}, parent);
child.name = 'B'; // 父对象 name 不变
child.list.push(3); // 父对象 list 变成 [1, 2, 3]
想避免引用共享?得用深拷贝或构造函数隔离
如果父对象含嵌套结构,又希望子对象彻底独立,浅拷贝不够用。此时有两种务实路径:
- 用
JSON.parse(JSON.stringify(obj))(仅限纯数据,不含函数、undefined、Date 等) - 在子对象构造时重新初始化引用属性,比如:
function Child() { this.list = [...parent.list]; } - 结合构造函数继承(
Parent.call(this)),让每个实例拥有自己的一份引用类型副本
实际开发中更推荐组合继承而非纯浅拷贝
单纯浅拷贝父对象属性,既不能复用原型方法,又无法解决引用共享,属于临时取巧。真实项目中更常用的是:
- 组合式继承:用
Parent.call(this)继承实例属性,再用Child.prototype = Object.create(Parent.prototype)继承原型方法 - ES6 class + extends:底层自动处理上述逻辑,语义清晰,调试友好
- 工厂函数或 Object.create 配合属性重定义:适合轻量、无类场景
浅拷贝更适合配置合并、表单初始值克隆等一次性数据操作,而不是构建可扩展的对象继承关系。


















