JavaScript 原型继承机制与构造函数冲突解决
本文深入解析JavaScript基于原型的对象系统,阐明构造器与实例间的原型关系。重点探讨原型继承中constructor属性指向错误的常见陷阱,并提供重置constructor及通过静态变量调用父类方法的高级解决方案,辅以完整代码示例。
JavaScript原型继承基础
在JavaScript中,对象本身并不直接拥有原型属性,而构造器(Constructor)才具备原型对象。
原型的核心含义在于:若构造器定义了一个原型对象A,那么由该构造器创建的所有实例都将自动继承并复制自对象A。
具体实现代码如下:
/*申明2个构造器*/
var flower=function(){
this.name="nokia";
}
var flower2=function(){
this.age=22;
}
/*原型链*/
flower2.prototype=new flower();
/*根据刚才原型的定义,实例obj必然复制自new flower();*/
obj=new flowe2();
/*从父类继承的属性*/
alert(obj.name); //==>"nokia"
alert(obj.age); //==>22 通常情况下,由构造器生成的实例,其constructor属性默认指向该构造器本身。
alert(obj.constructor);//==>flower
同时,构造器原型(prototype)上的constructor属性也指向该构造器自身。
alert(flower.prototype.constructor==flower);//==>true
constructor属性冲突与解决
然而,在使用原型继承时,constructor属性往往会出现指向冲突的问题。
相关代码如下:
function flower(){}
function flower2(){}
flower2.prototype=new flower();
var obj1=new flower();
var obj2=new flower2();
/*问题出现了,2个实例的constructor属性都指向flower*/
alert(obj1.constructor==obj2.constructor);
/*obj1和obj2是不同的构造器产生的实例,缺指向相同的构造器,显然出了问题*/ 针对上述问题的解决方法如下:
具体代码实现为:
flower2.prototype=new flower();
/*重置原型后,修改原型的constructor属性*/
flower2.prototype.constructor=flower2
或者,在每次构造实例时手动重写constructor属性。
function flower2(){
this.constructor=arguments.callee;
}
flower2.prototype=new flower(); 父类方法调用的高级实现
此外,标准的原型继承机制并未直接提供调用父类方法的途径。
为弥补这一缺陷,我们可以基于原型继承,利用静态变量记录父类信息来实现对父类方法的调用。
相关实现代码如下:
var Class={
create:function()
{
var _class=function()
{
this.init.apply(this,arguments);
}
_class.prototype.init=Function.prototype.init;
try{
return _class;
}finally{
_class=null;
}
}
};
//默认构造函数
Function.prototype.init=function(){}
//方法扩展
Function.prototype.extend=function(list)
{
for(var i in list)this.prototype[i]=list[i];
return this;
}
//多级继承
Function.prototype.inherits=function(parent)
{
//继承的深度级别
var _depth=0;
//方法属性移植
this.extend(new parent());
//初始化构造函数 类的继承通常不继承构造函数
this.prototype.init=Function.prototype.init;
//类的静态父类
this.parent=parent;
//执行父类函数
this.prototype.parent=function(name)
{
//若没有参数则执行构造函数
if(!name)name='init';
//即将执行的父类
var _parent=parent;
//若当前已经在父类中执行则继续向上寻找超类
if(_depth)
{
for(var i=0;i<_depth;i++)
{
_parent=_parent.parent;
}
}
//设置好级别
_depth++;
try{
//执行函数并返回值
return _parent.prototype[name].apply(this,Array.prototype.slice.apply(arguments,[1]));
}catch(e){
throw(e);
}finally{
//恢复级别
_depth--;
}
}
return this;
} 示例演示如下:
具体代码为:
//创建名为class1的构造器
var class1=Class.create().extend({
b:function()
{
alert('clas');
alert(this.c);
},
c:100
});
//创建"对象"(构造器)的实例
var s=new class1();
s.b();// ==>"clas",100 关于继承父类并调用其方法的实现:
代码如下:
var test=Class.create().inherits(class1).extend({
b:function()
{
alert('test');
this.parent('b')
},
c:110
}); JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
JavaScript新手常犯的编码错误与最佳实践指南
2026-11-04 22:12:38
