javascript继承

1, 缺点,给子类prototype添加新方法只能一个一个添加,不能直接传一个对象(方法集合),否则会覆盖继承的父类的方法。

 1 Function.prototype.inherit = function(baseClass){

 2     for(var i in baseClass.prototype){

 3         this.prototype[i] = baseClass.prototype[i];

 4     }

 5 }

 6 function BaseClass(){}

 7 BaseClass.prototype = {

 8     method1:function(){

 9         alert('method1');

10     },

11     method2:function(){

12         alert('method2');

13     }

14 };

15 

16 function ClassA(){}

17 ClassA.inherit(BaseClass);

18 ClassA.prototype.method1 = function(){alert(0);};

19 var obj = new ClassA();

20 obj.method1();

21 var obj2 = new BaseClass();

22 obj2.method1();

2, 缺点是继承必须Class.prototype = (new BaseClass()).extend({.....});这样写,习惯了java这类面向对象语言的继承的人,估计看着这样的写法会有点别扭,比如我就觉得这样挺别扭的。不过习惯了就好,jquery的继承写法不也跟这样类似么。其实下面这代码就是prototype-1.3.1框架里继承的写法。我按照书上写的。

Object.extend = function(des,source){

    for(var property in source){

        des[property] = source[property];

    }

    return des;

};

Object.prototype.extend = function(object){

    return Object.extend.apply(this,[this,object]);

};



function BaseClass(){

    this.name = "name";

};

BaseClass.prototype = {

    method1:function(){alert('method1');},

    method2:function(){alert('method2');}

};



function Class(){};

Class.prototype = (new BaseClass()).extend({

    method1:function(){alert('extend');},

    m1:function(){alert('m1');},
  age:'age' });
var a = new Class(); a.method1(); a.method2(); a.m1(); alert(a.name);

留给自己的问题,如果有谁看到, 并且知道,请告知,谢谢。

这种写法,会将父类构造器里定义的属性也赋给继承类的prototype,即使这些属性的值是undefined,占不占用内存?如果继承时候用apply或者call来继承了基类的属性,如

1 function BaseClass(name){

2     this.name = name;

3 };

4 function Class(name,age){

5    BaseClass.call(this, name); 

6 };

然后再用上面的 Class.prototype = (new BaseClass()).extend({.....}); 这个时候,Class有一个name属性,而Class.prototype里应该是也有个name属性,只不过它的值是undefined。在使用的时候,似乎是没有什么问题的,可是我突然想,Class.prototype.name是否会占用一个空间呢?如果占用,这个空间被占用却又没有什么用处,然而这点被占用的空间几乎又并不是很大,是忽略它呢还是应该去优化呢?哎,想到这里,似乎这又并不是一个什么问题了,一个类浪费了这么一点空间,似乎并不是什么大问题。

 

2014.4.16  补充编辑

 

接上面的问题,Class.prototype.name是一个属性,自然会占用空间,只不过它指向了window.undefined。这在对Class的对象的属性查找时候,会增加资源消耗。

解决办法:自定义一个prototype对象,将构造函数也定义在prototype对象里,然后用一个通用函数来创建类的实例对象。

如下

 

 1 //通用创建函数

 2 function New(aClass, aParams)

 3 {

 4     function new_()

 5     {

 6         //调用原型中定义的构造函数,中转构造逻辑及构造参数

 7         aClass.Create.apply(this,aParams);

 8     };

 9     //中转原型对象

10     new_.prototype = aClass;

11     //返回最终建立的对象,在退出函数体的时候,new_ 函数对象会被释放。

12     return new new_();

13 };

14 //定义的类(自定义的原型,将类的构造函数放在原型对象里)

15 var Person = {

16     Create:function(name,age)

17     {

18         this.name = name;

19         this.age = age;

20     },

21     SayHello:function()

22     {

23         alert("Hello,I'm " + this.name);

24     },

25     HowOld:function()

26     {

27         alert(this.name + " is " + this.age + " years old.");

28     }

29 };

30 

31 //调用通用函数创建对象,并以数组形式传递构造参数

32 var BillGates = New(Person,["Bill Gates",59]);

33 BillGates.SayHello();

34 BillGates.HowOld();

 

这种写法,很类似于c#的对象语言形式,代码看起来会很优雅。而且这种写法的JavaScript 程序效率会更高。因为其原型对象里既没有了毫无用处的那些对象级的成员,而且还不存在constructor 属性体(新建的对象自己及其原型里没有constructor 属性,返回的是最顶层原型对象的构造函数,即Object),少了与构造函数间的牵连,但依旧保持了方法的共享性。这让JavaScript 在追溯原型链和搜索属性及方法时,会快捷一些。

用于继承也是一样的,如

 1 //通用的继承方法(自定义的prototype对象)

 2 function Class(aBaseClass, aClassDefine){

 3     function class_(){

 4                 //Type指向基类

 5         this.Type = aBaseClass;

 6         for(var member in aClassDefine){

 7                         //复制类的全部定义到当前创建的类

 8             this[member] = aClassDefine[member];

 9         }

10     };

11     class_.prototype = aBaseClass;

12     return new class_();

13 }

14     

 

 

你可能感兴趣的:(JavaScript)