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     

 

 

posted @ 2014-03-28 14:41  青椒炒蛋  阅读(351)  评论(0编辑  收藏  举报