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

Javascript原型链

众所周知,Javascript使用原型链来实现面向对象的继承关系。

?

下面我们就拿一段Prototype框架中的创建对象的代码片段来分析对象继承是如何实现的(注意prototype和constructor的用法):

function subclass() {}; //定义一个空函数
  function create() {
    var parent = null, properties = $A(arguments); //分析入参
    if (Object.isFunction(properties[0])) //查看第一个参数时候是函数,如果是函数,把它作为父对象
      parent = properties.shift();

    function klass() { //定义对象创建函数
      this.initialize.apply(this, arguments); //入参中一般必须包含一个initialize方法,就像对象的构造函数一样,如果没有定义,会自动使用一个空函数替代
    }

    Object.extend(klass, Class.Methods); //扩展Prototype自定义的一些方法,略过
    klass.superclass = parent; //定义一个对象属性superclass,指向父对象
    klass.subclasses = []; //定义一个数组属性subclasses,用于存放所有的子对象

    if (parent) { //如果存在父对象的话
      subclass.prototype = parent.prototype; //先将子对象的prototype属性指向父对象,从而继承了父对象的所有属性及方法
      klass.prototype = new subclass; //这里是最关键的地方,通过对子对象prototype的赋值,达到继承了父对象所有属性及方法的目的
      parent.subclasses.push(klass); //然后更新父对象的子对象数组
    }

    for (var i = 0, length = properties.length; i < length; i++)
      klass.addMethods(properties[i]);  //把入参中出去父对象之外的所有属性添加至新创建的对象中

    if (!klass.prototype.initialize) //如果没有定义initialize方法,会使用一个空函数来替代
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass; //由于创建过程中修改了prototype属性,导致现在新创建的对象的构造函数指向父对象,这里重新把构造函数修改成对象本身
    return klass; //返回对象创建函数
  }

?

至此,一个对象就创建好了,通过下面的例子就一目了然了。

var User = Class.create({
   initialize: function(name){
        this.name = name;
   },
   getName: function(){
       return this.name;
   }
})

?创建一个带有父对象的新对象

var Account = Class.create(User, {
   initialize: function(bankInfo){
        this.bankInfo = bankInfo;
   },
   getBankInfo: function(){
       return this.bankInfo;
   }
})

?这样,一个继承自User对象的Account对象就创建好了,是不是很简单啊。

?