JavaScript 原型链继承封装:Factory 模式实战解析

作者:木棉时间:2026-10-24 13:37:12浏览:116

本文深入解析 JavaScript 中基于原型链的继承机制,通过 Factory 对象封装 Create 和 CreateBaseClass 方法,实现类与子类的继承关系。文章对比了传统直接赋值原型链与辅助函数封装两种方式,详细演示如何利用临时构造函数和 apply 方法优化继承结构,并提供清晰与优雅两种代码实现方案供开发者参考。

JavaScript 原型链继承封装:Factory 模式实战解析

接下来我们将逐步构建这一机制,首先回顾一下 JavaScript 中继承的传统写法。


具体实现代码如下:

 
<script>
var Person = function(name, age) {
this.name = name;
this.age = age;
} 
Person.prototype.SayHello = function () {
alert(this.name + "," + this.age);
}; 
var Programmer = function (name, age, salary) {
Person.call(this, name, age);
this.salary = salary;
}; 
Programmer.prototype = new Person();
var pro = new Programmer("kym", 21, 500);
pro.SayHello();
</script>

从上述代码可以看出,继承的核心在于执行 `Programmer.prototype = new Person()` 这一步操作,即将 Person 实例赋值给 Programmers 的原型,从而将 Person 加入原型链。关于原型链原理的详细解释,可参考《Javascript 学习笔记 7——原型链的原理》。


因此,实现继承的关键在于如何正确构建和管理原型链。


在前文中,我们使用 JSON 对象构建原型,其原型链关系表现为 `p.__proto__ = Person`。若在此基础上封装继承,理想的原型链应为 `p.__proto__.__proto__ = SuperClass`,即 `Person.__proto__ = SuperClass`。然而,按照上述代码的继承方式,实际形成的原型链关系是 `Person.__proto__ = SuperClass.prototype`。


为了解决这一差异,我们可以借鉴前文的方法,借助一个辅助函数,将原函数内的属性赋值给该辅助函数,并令其 `prototype` 指向 `SuperClass`,从而实现对子原型的封装。


基于上述思路,我们来实现利用原型链进行继承关系的封装。


具体代码如下:

 
<script>
var Factory = {
Create: function (className, params) {
var temp = function () {
className.Create.apply(this, params);
}; 
temp.prototype = className;
var result = new temp();
return result;
}, 
CreateBaseClass: function (baseClass, subClass) {
var temp = function () {
for (var member in subClass) {
this[member] = subClass[member];
} 
}; 
temp.prototype = baseClass;
return new temp();
} 
}; 
var People = {
Create: function (name, age) {
this.name = name;
this.age = age;
}, 
SayHello: function () {
alert("Hello,My name is " + this.name + ".I am " + this.age);
} 
}; 
var Temp = {
Create: function (name, age, salary) {
People.Create.call(this, name, age);
this.salary = salary;
}, 
Introduce: function () {
alert(this.name + "$" + this.age + "$" + this.salary);
} 
}; 
var Programmer = Factory.CreateBaseClass(People, Temp);
var pro = Factory.Create(Programmer, ["kym", 21, 500]);
pro.SayHello();
</script>

至此,我们完成了对继承关系的封装。当然,我们也可以不单独定义变量,直接内联处理:


代码如下:

 
var Programmer = Factory.CreateBaseClass(People,
{ 
Create: function (name, age, salary) {
People.Create.call(this, name, age);
this.salary = salary;
}, 
Introduce: function () {
alert(this.name + "$" + this.age + "$" + this.salary);
} 
}); 

这完全取决于个人编码习惯。个人认为第一种方法结构相对更清晰,而第二种方法则在代码形式上更为优雅。

作者最新文章