背景
在上篇文章中,我簡單的介紹了如何實現單繼承。只是在子類中調用父類方法的方式讓人感覺不是很爽:
1 var Animal = function () { 2 Animal.super().constructor.apply(this, arguments); 3 };
今天這篇文章的目的就是簡化這種調用方式,期望的調用方式如下:
1 var Animal = function () { 2 this.callParent(arguments); 3 };
如何實現callParent呢?
只要做到如下幾點,實現callParent就不是問題了,要求如下:
-
- callParent必須知道哪個方法調用的它。
- callParent必須知道調用它的那個方法的名字。
- callParent必須知道調用它的那個方法的擁有者(prototype)。
- 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中。
