object.create()是原型式继承的直接实现,通过设置新对象的__proto__指向指定源对象建立委托链,不涉及构造函数或this绑定。

Object.create() 是原型式继承最直接的实现方式,用它创建的对象,其 __proto__ 会明确指向你指定的源对象,从而触发属性查找时的委托机制。它不涉及构造函数、new 或 this 绑定,纯粹靠原型链连接两个对象。
怎么用:参数和常见写法
基本语法是 Object.create(proto, propertiesObject),其中 proto 是必需的,propertiesObject 可选。
- 只传原型对象:const child = Object.create({ name: 'Alice' }); —— child 能读取 name,但自身无该属性
- 传 null:const obj = Object.create(null); —— 得到一个真正“干净”的空对象,没有 toString、hasOwnProperty 等原生方法
- 传 Object.prototype:const obj = Object.create(Object.prototype); —— 效果等同于 {} 或 new Object()
- 加自有属性:Object.create(parent, { age: { value: 30, writable: true } }) —— 第二个参数结构和 Object.defineProperties 一致,定义的是新对象自身的属性
底层原理:本质是“函数中转 + 原型赋值”
它内部模拟了一个临时构造函数,把传入的 proto 设为其 prototype,再用 new 调用,最终返回的实例自然就把 __proto__ 指向了 proto。
- 相当于执行了类似这样的代码:function F() {} F.prototype = proto; return new F();
- 这个临时函数 F 在调用后就不再被引用,会被垃圾回收,真正留下的是新对象与 proto 之间的原型链关系
- 所以 Object.create 并不是“复制”源对象,而是建立一条委托链:访问属性时先查自身,找不到就顺着 __proto__ 找过去
需要注意的典型问题
原型式继承的核心优势是轻量、灵活,但共享引用类型属性容易引发意外修改。
- 如果父对象里有数组或对象(如 { friends: [] }),子对象直接 push 或修改,所有共享该原型的对象都会看到变化
- 解决办法是:在子对象上重新赋值该属性(比如 child.friends = []),切断委托,变成自有属性
- 它不适合需要私有状态或初始化逻辑的场景——没有构造函数,无法自动运行初始化代码
和其它继承方式的关键区别
它不依赖构造函数,也不修改原有对象,只是让新对象“以它为原型”。这使得对象复用更直观,也更容易做配置化继承(比如基于某个默认配置对象派生多个实例)。
- 对比寄生组合式继承:Object.create 更简单,但缺少对 constructor 的自动维护,需手动设置
- 对比 class extends:后者是语法糖,底层仍靠 Object.create 实现原型链连接
- 它更适合数据驱动、配置驱动的场景,比如构建 UI 组件模板、状态基类、配置合并等











