1. `Child.prototype = Object.create(Parent.prototype);`
- **行为**:创建一个新对象,其原型指向 `Parent.prototype`,并将该对象赋值给 `Child.prototype`。
- **结果**:
- **替换原型**:原有的 `Child.prototype` 被完全替换,丢失所有原有属性/方法。
- **原型链**:新对象的 `__proto__` 指向 `Parent.prototype`,实现继承。
- **Constructor 问题**:新对象的 `constructor` 属性指向 `Parent`,需手动修正:`Child.prototype.constructor = Child;`。
- **适用场景**:标准继承模式,推荐在 ES5 中使用,需注意修正 `constructor`。
2. `Child.prototype.__proto__ = Parent.prototype;`
- **行为**:直接修改现有 `Child.prototype` 对象的 `__proto__`,使其指向 `Parent.prototype`。
- **结果**:
- **保留原有属性**:`Child.prototype` 的原有属性/方法得以保留。
- **原型链**:通过修改 `__proto__` 继承 `Parent.prototype`,无需创建新对象。
- **Constructor 问题**:若 `Child.prototype` 已有正确 `constructor`,则无需修正。
- **注意事项**:
- `__proto__` 并非所有环境支持(ES6 标准化为可选特性)。
- 可能影响性能或引发兼容性问题。
核心区别
| 特性 | `Object.create` | 直接修改 `__proto__` |
|---------------------|-----------------------------------------|------------------------------------|
| **原型对象替换** | 是(新对象替换原有 `Child.prototype`) | 否(修改现有对象的原型链) |
| **原有属性保留** | 否(需重新添加属性) | 是(保留原有属性) |
| **Constructor 处理** | 需手动修正 | 依赖原有 `constructor` 是否正确 |
| **兼容性** | ES5+ 标准方法,广泛支持 | 依赖 `__proto__` 支持,可能存在兼容性问题 |
示例代码
javascript
// 方式 1:Object.create
function Parent() {}
function Child() {}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child; // 修正 constructor
Child.prototype.childMethod = function() {};
// 方式 2:修改 __proto__
function Parent() {}
function Child() {}
Child.prototype.childMethod = function() {}; // 提前定义方法
Child.prototype.__proto__ = Parent.prototype; // 继承且保留 childMethod
总结
- **推荐使用 `Object.create`**:符合标准,逻辑清晰,但需修正 `constructor`。
- **慎用 `__proto__`**:适用于需保留原型属性的场景,注意兼容性和潜在问题。
- **ES6 替代方案**:使用 `class Child extends Parent {}` 语法糖,自动处理原型链和 `constructor`。