JavaScript 对象继承机制详解:原型链、构造函数与组合模式

作者:闭包旅人时间:2026-10-27 05:29:29浏览:385

本文深入解析 JavaScript 中的对象继承机制,涵盖原型链、借用构造函数及组合继承等核心模式。通过代码示例演示如何定义超类与子类,讲解 instanceof 和 isPrototypeOf 判断关系,并对比各模式的优缺点,如属性共享、参数传递及函数复用问题,帮助开发者掌握最实用的继承方案。

原型链继承机制

1. 原型链


// 很少单独使用


代码如下:

 
View Code
// 定义 SuperClass 类,包含一个属性 property 和一个方法 getSuperValue
function SuperClass() {
this.property = true;
} 
SuperClass.prototype.getSuperValue = function() {
return this.property;
} 
// 定义 SubClass 类,包含属性 subproperty 以及后续添加的方法 getSubValue
function SubClass() {
this.subproperty = false;
} 
// SubClass 类继承 SuperClass 类
SubClass.prototype = new SuperClass();
// SubClass 类添加一个方法 getSubValue
SubClass.prototype.getSubValue = function() {
return this.subproperty;
} 
// 创建 SubClass 类的实例
var instance = new SubClass();
alert(instance.getSuperValue());

判断原型与实例关系

2. 确定原型与实例的关系


第一种方式是利用 instanceof 操作符,用于测试实例是否属于原型链中出现的构造函数


代码如下:

 
alert(instance instanceof Object); // true,instance 是 Object 的实例吗?
alert(instance instanceof SuperClass); // true,instance 是 SuperClass 的实例吗?
alert(instance instanceof SubClass); // true,instance 是 SubClass 的实例吗?

第二种方式是利用 isPrototypeOf() 方法,用于测试原型链中出现的原型对象


代码如下:

 
alert(Object.prototype.isPrototypeOf(instance)); // true
alert(SuperClass.prototype.isPrototypeOf(instance)); // true
alert(SubClass.prototype.isPrototypeOf(instance)); // true

原型链定义方法的注意事项

3. 用原型链继承定义方法时的注意点


定义方法的顺序至关重要:


代码如下:

 
View Code
function SuperClass() {
this.property = true;
} 
SuperClass.prototype.getSuperValue = function() {
return this.property;
} 
function SubClass() {
this.subproperty = false;
} 
// SubClass 继承 SuperClass
SubClass.prototype = new SuperClass(); // 这行代码必须先执行,新添加的方法和重写超类的方法必须写在后面,否则重写的超类方法将永远无法被调用
// 添加新方法
SubClass.prototype.getSubValue = function() {
return this.subproperty;
} 
// 重写超类的方法
SubClass.prototype.getSuperValue = function() {
return false;
} 
var instance = new SubClass();
alert(instance.getSuperValue()); // false,这里 SubClass 的实例调用了 SubClass 的 getSuperValue() 方法,从而屏蔽了 SuperClass 的 getSuperValue() 方法
// 使用 SuperClass 的方法会调用 SuperClass 的 getSuperValue() 方法

原型链继承存在两个主要缺点:1)超类中的属性会被所有子类共享;2)在创建子类时无法向超类的构造函数传递参数。因此,原型链很少被单独使用



借用构造函数模式

4. 借用构造函数


// 很少单独使用



优点是可以向超类传递参数。缺点是函数无法复用,所有类都必须使用构造函数模式


代码如下:

 
View Code
function SuperClass(name) {
this.name = name;
} 
function SubClass() {
SuperClass.call(this, "RuiLiang"); // 继承了 SuperClass,同时向 SuperClass 传递了参数
this.age = 29; // 实例属性
} 
var instance = new SubClass();
alert(instance.name); // RuiLiang
alert(instance.age); // 29

组合继承模式

6. 组合继承


// 最常用的继承模式


代码如下:

 
View Code
// 创建 SuperClass
function SuperClass(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
} 
SuperClass.prototype.sayName = function() {
alert(this.name);
} 
// 创建 SubClass
function SubClass(name, age) {
SuperClass.call(this, name); // 继承属性
this.age = age; // 自己的属性
} 
SubClass.prototype = new SuperClass(); // 继承方法
SubClass.prototype.sayAge = function() { // SubClass 添加新方法
alert(this.age);
}; 
// 使用示例
var instance1 = new SubClass("RuiLiang", 30);
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "RuiLiang"
instance1.sayAge(); // 30
var instance2 = new SubClass("XuZuNan", 26);
alert(instance2.colors); // "red,blue,green"
instance2.sayName(); // "RuiLiang"
instance2.sayAge(); // 30

其他继承模式简介

7. 其它继承模式


原型式继承、寄生式继承、寄生组合式继承

作者最新文章