JS OO继承、多态

一般原型继承的写法 xxx.prototype = new Base();,但是new Base 这样的写法怎么能对构造器传入参数呢?明显写死了而不能传入参数——必然要有其他的做法。什么做法?我们很容易想到 sub.prototype = base.prototype,但这样直接的写法虽然看上去可以,实际上却很危险,因为这相当于设置同一个原型链(Prototype Chain)——在同一个类上修改 protoype 成员,原型链上一旦出现变动,就会影响了继承链,结果便是“子类修改了父类的行为”,让其他同级的子类也牵连进来——这万万不是我们想见到的情况,不可采用。于是再加权衡,想到了通过一个中介“类”Dummy Function 的方法,也就是 Douglas Crockford 给出的、曾经十分推崇的 Obejct.creat() 方法,——即可解决同一继承链种种不足所带来的问题。这正是 D.C 为何在他的文章中如此推崇Obejct.creat()方法的原因。本文篇幅所限,就不详细说个中原理了,都在 D.C 文章早有全面介绍。

继承的方法我定义在 Object.extend() 中,详细源码如下:

[javascript] view plain copy
  1. // @parma {Function} base 父类  
  2. // @parma {Function} sub 子类  
  3. Object.extend = function(base, sub){  
  4.     var dummy = function(){}  
  5.     dummy.prototype = base.prototype; // key step!  
  6.     var superObject = new dummy;  
  7.     var subProto = sub.prototype;  
  8.       
  9.     sub.prototype = superObject;  
  10.     sub.prototype.constructor = base;  
  11.       
  12.     for(var i in subProto){  
  13.         if(i in sub.prototype){  
  14.             sub.prototype["_" + i] = sub.prototype[i]; // 规定_开头为父类成员  
  15.             sub.prototype[i]       = subProto[i];  
  16.         }else{  
  17.             sub.prototype[i] = subProto[i];  
  18.         }  
  19.     }  
  20.     return sub;  
  21. }  

测试代码如下(在winxp sp3/IE6上通过):

[javascript] view plain copy
  1. function base(a1, a2){  
  2.     this.a1 = "init...base class, the value is " + a1;  
  3.     this.a2 = a2;  
  4. }  
  5. base.prototype = {  
  6.     sayHi:function (){  
  7.         this.sayingHi = true;  
  8.         return "Hello";  
  9.     }  
  10. };  
  11. function sub(a3, a4){  
  12.     //base.apply(this, [1]);  
  13.     this.a2 = 2;      
  14.     this.a3 = 'init...sub class, the value is ' + a3;  
  15.     this.a4 = a4;  
  16. }  
  17. sub.prototype.sayHi = function(){  
  18.     var hi = base.prototype.sayHi.call(this) + " World"  
  19.     return hi;    
  20. }  
  21. sub.print = function(_instance){  
  22.     return _instance.saiHi();  
  23. }  
  24. function sub2(){}  
  25. sub2.prototype.sayHi = function(){  
  26.     return this._sayHi() + ' Man!';  
  27. }  
  28. _extend(base, sub);  
  29. _extend(sub, sub2);  
  30. foo = new sub2;  
  31. alert(foo.sayHi());  
  32. lert(foo instanceof base);  

另外,还根据上述继承的思路炮制了一个 Obejct.mix() 多态应用。所谓的多态,于此表现得也比较简单了,说穿了仍然是常见的“复制成员到某地”。

[javascript] view plain copy
  1. // @parma {Function} class 父类  
  2. // @parma {Function} mix 多态类  
  3. Object.mix = function(_class, mix){  
  4.     var   
  5.          classProto = _class.prototype  
  6.         ,mixProto   = mix.prototype;  
  7.       
  8.     for(var i in mixProto){  
  9.         if(i in classProto){  
  10.             classProto["_" + i] = mixProto[i];  
  11.         }else{  
  12.             classProto[i] = mixProto[i];  
  13.         }  
  14.     }  
  15. }  

以上几点算不上思路,偶有所得,大家来谈谈亦无妨。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值