日期:2014-05-16  浏览次数:20369 次

精通Javascript 之 继承
原型式继承

 原型式继承类似于一种单继承,它利用prototype属性,prototype可以整个复制一个对象,但是它不会从其他原型或者构造函数中继承属性,而属性都是从实际对象那里继承过来的。

        //创建Person的构造函数
         function Person(name) {
             this.name = name;
         }
         //Person添加一个新方法
         Person.prototype.getName = function () {
             return this.name;
         };
         //创建User构造函数
         function User(name, password) {
             //注意:这里并没有支持方便的重载和继承,也就是说不能调用父类的构造函数
             this.name = name;
             this.password = password;
         };
         //User继承所有的Person对象的方法
         User.prototype = new Person();
         //我们添加一个新方法到User对象中
         User.prototype.getPassword = function () {
             return this.password;
         };

 上面这个例子最重要的一行是User.prototype=new Person();. User是对User对象构造函数的引用。new Person()使用Person构造函数创建了一个新的Person对象,然后把User构造函数的原型置为这个操作的结果。也就是说,每当new User()的时候,得到的新User对象都会带有Person对象所有的方法,如同通过操作new Person()得到的一样。
 
 类继承

 JS里不支持java、c++那样的类继承方式,但是这种继承方式在使用上是非常方便的。现在有很多JS类库提供类似的解决方法,我们这里看一下Prototype库是如何实现的呢。

// 创建一个名为 'Class'的全局对象
 var Class = {
     //它只有一个函数,其作用是创建一个新的对象构造函数
     create: function () {
         //创建一个匿名的对象构造函数
         return function () {
             //调用它本身的初始化方法
             this.initialize.apply(this, arguments);
         }
     }
 }
 
 //给Object对象添加一个新的静态方法,它的作用是把属性从一个对象复制到另一个中
 Object.extend = function (destination, source) {
     //遍历所有要扩展的属性
     for (property in source) {
         //然后把他们添加到目标对象中
         destination[property] = source[property];
     }
     //返回修改后的对象
     return destination;
 }

 拿来小用一下:

        //创建一个新的构造函数为空的Person对象
         var Person = Class.create();
         //将下面的函数复制到Person的prototype中
         Object.extend(Person.prototype, {
             //这个函数由Person构造函数立即调用
             initialize: function (name) {
                 this.name = name;
             },
             //Person对象的简单函数
             getName: function () {
                 returnthis.name;
             }
         });
         //创建一个构造函数为空的User对象
         var User = Class.create();
 
         //User对象继承了所有的父类的函数
         User.prototype = Object.extend(new Person(), {
             //将父类的初始化函数重载为新的
             initialize: function (name, password) {
                 this.name = name;
                 this.password = password;
             },
             //给这个对象添加一个新的函数
             getPassword: function () {
                 returnthis.password;
             }
         });
 
         //看看我们创造出来的两个类吧
         var person = new Person("Lisa");
         var user = new User("Lisa", "123");

 Prototype确实只使用了两个简单的函数来创建和管理整个面向对象结构,这两个函数的出发点很简单:
 Class.create():整个函数仅仅使用一个匿名函数封装起来作为构造函数。这种简单的构造函数只做一件事情——调用并执行对象的initialize属性。如果对象中不包含initialize属性就会抛异常。
 Object.extend():这个只是把所有属性从一个对象复制到另一个对象。
 虽然这个技术很复杂,但是提供的面向对象需要的基本功能。