Javascript:繼續實現繼承,支持:this.callParent(arguments)


背景

上篇文章中,我簡單的介紹了如何實現單繼承。只是在子類中調用父類方法的方式讓人感覺不是很爽:

1 var Animal = function () {
2     Animal.super().constructor.apply(this, arguments);
3 };

今天這篇文章的目的就是簡化這種調用方式,期望的調用方式如下:

1 var Animal = function () {
2     this.callParent(arguments);
3 };

如何實現callParent呢? 

只要做到如下幾點,實現callParent就不是問題了,要求如下:

    1. callParent必須知道哪個方法調用的它。
    2. callParent必須知道調用它的那個方法的名字。
    3. callParent必須知道調用它的那個方法的擁有者(prototype)。
    4. callParent必須知道調用它的那個方法的擁有者的父類。

思路有了,實現就不是問題了

因為默認情況Javascript只支持1,而2、3和4都要在框架層面做出約束,框架要做的就是:一、為類型和方法增加相應的元數據;二、類型的方法定義必須使用Class.defineMethod方法進行定義。

代碼示例

 1 Function.prototype.defineMethod = function (methodName, methodBody) {
 2      this.prototype[methodName] = methodBody;
 3      methodBody.$name = methodName;
 4      this.$owner = this;
 5  };
 6 
 7 Function.prototype.extend = function (baseType) {
 8      var tempType = function () { };
 9      tempType.prototype = baseType.prototype;
10  
11      this.prototype = new tempType();
12      this.prototype.constructor = this;
13      this.prototype.callParent = function () {
14          var method = arguments.callee.caller;
15          
16          return method.$owner.$baseType.prototype[method.$name].apply(this, arguments);
17      };
18 
19      this.$baseType = baseType;
20      this.defineMethod('constructor', this.prototype.constructor);
21      this.super = function () {
22          return baseType.prototype;
23      };
24  };
25 
26 
27  
28  var Base = function (name) {
29      console.log('Base');
30      this.name = name;
31  };
32  
33  var Animal = function () {
34      this.callParent(arguments);
35      console.log('Animal');
36  };
37  Animal.extend(Base);
38 
39  var Dog = function () {
40      this.callParent(arguments);
41      console.log('Dog');
42  };
43  Dog.extend(Animal);
44 
45  var dog = new Dog('懶狗');

備注

整個實現有點借鑒ExtJS,當然ExtJS實現的就更完美了。我也有想法,希望把ExtJS的核心移植到NodeJS中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM