======================================================
注:本文源代码点此下载
======================================================
如何像c#,php那样在javascript中设计那种,可以继承的库呢?
带着这个问题,先看一段代码(前提架设你对prototype的工作原理是了解的。不了解的话请参看我的另一篇文章,面向对象的javascript和prototype的理解)
1 function testbase()
2 {
3this.namealias="testbasename";
4this.at=function(){alert("tttt");}
5 }
6
7 function subtestone()
8 {
9//加入一些特有的属性和方法
10this.subtest="one";
11 }
12
13 function subtesttwo()
14 {
15//加入一些特有的属性和方法
16this.subtest="two";
17 }
18
19 subtestone.prototype.base=new testbase;
20 subtesttwo.prototype.base=new testbase;
21
22 subtestone.prototype.atest=function() {alert("subtestone");}
23 subtesttwo.prototype.atest=function() {alert("subtesttwo");}//
24 var objone=new subtestone;
25 objone.atest();//output subtestone
26 objone.subtest;//output one
27 objone.base.namealias;//output testbasename
28
29 var objtwo=new subtesttwo;
30 objtwo.atest();//output subtesttow
31 objtwo.subtest;//output two;
32 objtwo.base.namealias;//output testbasename
因为上面的base是一个对象,直接在这里加入,是需要消耗特定的资源的。那么对于我们肯定是希望当使用到的时候才进行添加,为此我们需要对上面的代码进行改造,在改造之前我们先温习一个概念
1、testbase类的prototype含有属性constructor指向自身
也就是testbase.prototype.constructor指向testbase这个function
有两种调用testbase构造函数的方法:
→testbase.prototype.constructor();
→testbase.prototype.constructor.call();
接下来,我们做些改造,看代码
function testbase(str)
{
this.name1="name";
this.at=function(){alert("tttt");}
alert("testbase constructor");
}
function subtestone()
{
var baseobj;
this.base=function(){
if(baseobj==null)
baseobj= (new this.baseclass.prototype.constructor);
return baseobj;
}
this.subtest="one";
}
subtestone.prototype.baseclass=testbase;
subtestone.prototype.atest=function() {alert("subtestone");}
var t=new subtestone;
t.atest();
t.base().name1;
这里为了简化,把一些非主要的代码去掉了。现在,我们可以再需要用到其基类的时候,去构造。不需要的时候不需要。
咦,怎么感觉有点走偏了?的确没有错,这里其实是应该说,我们发现了一种聚合且延迟加载的方法。其实我们最一开始的实现方式也更像聚合。
但是我们这里不是要实现继承吗?对的,聚合和继承其实在功能上还是有不少地方相似的。因为javascript没有类似c#中的继承(就是继承后直接用.xxx就可以访问到基类的属性或方法)机制(不过今后会介绍如何利用技巧实现这个特点),必须使用另一个变量做暂存。(至少以我目前的认知是这样。如果有错误的地方希望高手不吝赐教)。所以,我们走着走着才像内聚。其实到现在这里,我们还有一个继承的特点没有说,就是子类初始化,还会调用父类的构造函数。这个很简单。只要在子类的构造函数中加入this.base();语句即可。把上面的代码改造后,就成了
1 function testbase(str)
2 {
3this.name1="name";
4this.at=function(){alert("tttt");}
5alert("testbase constructor");
6 }
7
8 function subtestone()
9 {
11var baseobj;
12this.base=function(){
13if(baseobj==null)
14baseobj= (new this.baseclass.prototype.constructor);
15return baseobj;
16}
17this.base();
19this.subtest="one";
20 }
21
22
23
24
25 subtestone.prototype.baseclass=testbase;
26 subtestone.prototype.atest=function() {alert("subtestone");}
27 var t=new subtestone;
28 //t.atest();
29 //t.base().name1;
注意17行,此行为唯一改动行。以上的方案中的第11行-17行,需要在每个子类中使用。这里目前还没有想到很好的复用方法。也希望有经验的多给些意见。
作者:roy lio
出处:http://josephliu.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
绿色通道:好文要顶关注我收藏该文与我联系
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/