视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
javascript几种模拟支持继承的用法实例总结
2020-11-27 20:15:17 责编:小采
文档


在javascript中,并不直接从方法上支持继承,模拟方法可以归纳为四种:构造继承法,原型继承法,实例继承法和拷贝继承法。融会贯通之后,还有混合继续法,这是什么法,就是前面四种挑几种混着来~

构造继续法例子:

//定义一个Collection类型 
function Collection(size) 
{ 
this.size = function(){return size}; //公有方法,可以被继承 
} 
Collection.prototype.isEmpty = function(){ //静态方法,不能被继承 
return this.size() == 0; 
} 
//定义一个ArrayList类型,它"继承"Collection类型 
function ArrayList() 
{ 
var m_elements = []; //私有成员,不能被继承 
m_elements = Array.apply(m_elements, arguments); 
//ArrayList类型继承Collection 
this.base = Collection; 
this.base.call(this, m_elements.length); 
this.add = function() 
{ 
return m_elements.push.apply(m_elements, arguments); 
} 
this.toArray = function() 
{ 
return m_elements; 
} 
} 
ArrayList.prototype.toString = function() 
{ 
return this.toArray().toString(); 
} 
//定义一个SortedList类型,它继承ArrayList类型 
function SortedList() 
{ 
//SortedList类型继承ArrayList 
this.base = ArrayList; 
this.base.apply(this, arguments); 
this.sort = function() 
{ 
var arr = this.toArray(); 
arr.sort.apply(arr, arguments); 
} 
} 
//构造一个ArrayList 
var a = new ArrayList(1,2,3); 
dwn(a); 
dwn(a.size()); //a从Collection继承了size()方法 
dwn(a.isEmpty); //但是a没有继承到isEmpty()方法 
//构造一个SortedList 
var b = new SortedList(3,1,2); 
b.add(4,0); //b 从ArrayList继承了add()方法 
dwn(b.toArray()); //b 从ArrayList继承了toArray()方法 
b.sort(); //b 自己实现的sort()方法 
dwn(b.toArray()); 
dwn(b); 
dwn(b.size()); //b从Collection继承了size()方法

原型继承法例子:

//定义一个Point类型 
function Point(dimension) 
{ 
this.dimension = dimension; 
} 
//定义一个Point2D类型,"继承"Point类型 
function Point2D(x, y) 
{ 
this.x = x; 
this.y = y; 
} 
Point2D.prototype.distance = function() 
{ 
return Math.sqrt(this.x * this.x + this.y * this.y); 
} 
Point2D.prototype = new Point(2); //Point2D继承了Point 
//定义一个Point3D类型,也继承Point类型 
function Point3D(x, y, z) 
{ 
this.x = x; 
this.y = y; 
this.z = z; 
} 
Point3D.prototype = new Point(3); //Point3D也继承了Point 
//构造一个Point2D对象 
var p1 = new Point2D(0,0); 
//构造一个Point3D对象 
var p2 = new Point3D(0,1,2); 
dwn(p1.dimension); 
dwn(p2.dimension); 
dwn(p1 instanceof Point2D); //p1 是一个 Point2D 
dwn(p1 instanceof Point); //p1 也是一个 Point 
dwn(p2 instanceof Point); //p2 是一个Point

实例继承法例子:
在说此法例子之前,说说构造继承法的局限,如下:

function MyDate() 
{ 
this.base = Date; 
this.base.apply(this, arguments); 
} 
var date = new MyDate(); 
alert(date.toGMTString); //undefined,date并没有继承到Date类型,所以没有toGMTString方法

核心对象的某些方法不能被构造继承,原因是核心对象并不像我们自定义的一般对象那样在构造函数里进 行赋值或初始化操作 换成原型继承法呢?,如下:

function MyDate(){} 
MyDate.prototype=new Date(); 
var date=new MyDate(); 
alert(date.toGMTString); //'[object]'不是日期对象,仍然没有继承到Date类型!

现在,换成实例继承法:

function MyDate() 
{ 
var instance = new Date(); //instance是一个新创建的日期对象 
instance.printDate = function(){ 
document.write("<p> "+instance.toLocaleString()+"</p> "); 
} //对instance扩展printDate()方法 
return instance; //将instance作为构造函数的返回值返回 
} 
var myDate = new MyDate(); 
dwn(myDate.toGMTString()); //这回成功
输出了正确的时间字符串,看来myDate已经是一个Date的实例 了,继承成功 myDate.printDate(); //如果没有return instance,将不能以下标访问,因为是私有对象的方法

拷贝继承法例子:

Function.prototype.extends = function(obj) 
{ 
for(var each in obj) 
{ 
this.prototype[each] = obj[each]; 
//对对象的属性进行一对一的复制,但是它又慢又容易引起问题 
//所以这种“继承”方式一般不推荐使用 
} 
} 
var Point2D = function(){ 
//…… 
} 
Point2D.extends(new Point()) 
{ 
//…… 
}

混合继承例子:

function Point2D(x, y) 
{ 
this.x = x; 
this.y = y; 
} 
function ColorPoint2D(x, y, c) 
{ 
Point2D.call(this, x, y); //这里是构造继承,调用了父类的构造函数 
//从前面的例子看过来,这里等价于 
//this.base=Point2D; 
//this.base.call(this,x,y); 
this.color = c; 
} 
ColorPoint2D.prototype = new Point2D(); //这里用了原型继承,让ColorPoint2D以Point2D对象为原型

下载本文
显示全文
专题