您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# JavaScript组合继承的示例分析
## 引言
在JavaScript面向对象编程中,继承是实现代码复用的重要机制。组合继承(Combination Inheritance)作为经典继承模式之一,结合了原型链继承和构造函数继承的优点,是ES6类语法出现前最常用的继承方式之一。本文将深入剖析组合继承的实现原理、代码示例、优缺点以及实际应用场景。
## 一、JavaScript继承概述
### 1.1 原型链继承的特点
```javascript
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child() {}
Child.prototype = new Parent(); // 原型链继承
const child = new Child();
child.sayName(); // 输出"parent"
问题:所有子类实例共享引用属性,且无法向父类传参。
function Parent(name) {
this.name = name;
}
function Child(name) {
Parent.call(this, name); // 构造函数继承
}
const child = new Child('child');
console.log(child.name); // 输出"child"
问题:无法继承父类原型上的方法。
组合继承通过以下两步实现:
1. 构造函数继承:使用Parent.call(this)
复制父类实例属性
2. 原型链继承:将子类原型指向父类实例
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 第二次调用Parent
this.age = age;
}
Child.prototype = new Parent(); // 第一次调用Parent
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
console.log(this.age);
};
// 测试用例
const child1 = new Child('Tom', 5);
child1.colors.push('green');
console.log(child1.colors); // ["red", "blue", "green"]
child1.sayName(); // "Tom"
child1.sayAge(); // 5
const child2 = new Child('Jerry', 3);
console.log(child2.colors); // ["red", "blue"]
[Child实例]
├─ 自身属性: name, age, colors (来自Parent.call)
└─ __proto__ → [Parent实例]
├─ 自身属性: name=undefined, colors=undefined
└─ __proto__ → [Parent.prototype]
├─ sayName()
└─ constructor: Parent
第一次调用(原型继承):
第二次调用(构造函数继承):
Child.prototype.constructor = Child;
必要性:防止原型链导致的constructor指向错误(默认会指向Parent)
function inheritPrototype(child, parent) {
const prototype = Object.create(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
inheritPrototype(Child, Parent);
class Parent {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
sayAge() {
console.log(this.age);
}
}
// 基础组件
function BaseComponent(element) {
this.element = document.querySelector(element);
this.init();
}
BaseComponent.prototype.init = function() {
console.log('Base initialized');
};
// 扩展组件
function DropdownMenu(selector) {
BaseComponent.call(this, selector);
this.isOpen = false;
}
DropdownMenu.prototype = new BaseComponent();
DropdownMenu.prototype.constructor = DropdownMenu;
DropdownMenu.prototype.toggle = function() {
this.isOpen = !this.isOpen;
console.log('Menu toggled:', this.isOpen);
};
// 游戏实体基类
function GameEntity(x, y) {
this.x = x;
this.y = y;
this.health = 100;
}
GameEntity.prototype.move = function(dx, dy) {
this.x += dx;
this.y += dy;
};
// 玩家角色
function Player(x, y, name) {
GameEntity.call(this, x, y);
this.name = name;
this.score = 0;
}
Player.prototype = new GameEntity();
Player.prototype.constructor = Player;
Player.prototype.collect = function(points) {
this.score += points;
};
继承方式 | 原型属性 | 实例属性 | 方法存储 |
---|---|---|---|
纯原型链继承 | 共享 | 共享 | 共享 |
构造函数继承 | 无 | 独立 | 无 |
组合继承 | 共享 | 独立 | 共享 |
// 测试代码示例
console.time('组合继承');
for(let i = 0; i < 100000; i++) {
new Child('test', i);
}
console.timeEnd('组合继承');
典型结果:组合继承比寄生组合继承慢约15-20%,但比纯原型链继承快30%左右
”`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。