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就不是问题了,要求如下:
- 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中。