JavaScript类式继承:实现多层继承与父类构造调用的方案

作者:代码拾荒时间:2026-10-27 04:15:14浏览:238

本文探讨JavaScript中实现类式继承的新尝试,旨在支持多层继承并简化父类构造函数的调用。通过自定义extend函数,利用$supClass属性动态指向父类,避免了一级继承之外的死循环问题,实现了类似其他语言的多层继承机制。

JavaScript类式继承的目标与效果

本次尝试的目标是优化JavaScript中的继承机制,使其更接近其他编程语言的使用习惯,重点解决多层继承以及方便调用父类构造函数的问题。


期望达到的效果如下所示。


具体实现代码如下:

 
function A(){
alert('a');
} 
function B(){
this.$supClass();
alert('b');
} 
extend(B,A);
function C(){
this.$supClass();
alert('c');
} 
extend(C,B);
var c = new C();
alert( c instanceof A ); //true
alert( c instanceof B ); //true
alert( c instanceof C ); //true

运行实例:


 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> js继承 </title> </head> <body> </body> </html> 

[[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]]


extend函数的实现原理

这里使用的extend函数实现方式如下:


代码如下:

 
function extend(subClass,supClass){
var fun = function(){},
prototype = subClass.prototype;
fun.prototype = supClass.prototype;
subClass.prototype = new fun();
for(var i in prototype){
subClass.prototype[i] = prototype[i];
 } 
subClass.$supClass = supClass;
subClass.prototype.$supClass = function(){
var supClass = arguments.callee.caller.$supClass;
if(typeof supClass == 'function'){
supClass.apply(this,arguments);
this.$supClass = supClass;
 } 
 }; 
subClass.prototype.constructor = subClass;
return subClass;
 } 

为何避免直接覆盖$supClass

或许有人会疑惑,为什么不采用如下写法:


代码如下:

 
function extend(subClass,supClass){
var fun = function(){},
prototype = subClass.prototype;
fun.prototype = supClass.prototype;
subClass.prototype = new fun();
for(var i in prototype){
subClass.prototype[i] = prototype[i];
} 
subClass.prototype.$supClass = function(){
supClass.apply(this,arguments);
}; 
subClass.prototype.constructor = subClass;
return subClass;
} 

这种写法看似合理,在仅有一级继承时运行正常,但在多层继承场景下会导致死循环。原因在于:


代码如下:

 
subClass.prototype.$supClass = function(){
supClass.apply(this,arguments);
}; 

该方法会被不断覆盖重写,从而引发死循环。


而我的做法是,将类的$supClass属性指向其继承的父类构造函数。同时在prototype中保留一个$supClass方法,该方法必须在类的构造器中首次执行。当执行prototype.$supClass时,会通过arguments.callee.caller.$supClass获取类的$supClass属性,再通过apply在this上执行。这样,$subClass就能根据不同层级获取对应的父类构造器并执行。

作者最新文章