现在的位置: 首页 > 综合 > 正文

javascript中最好用的extend继承方法

2012年09月19日 ⁄ 综合 ⁄ 共 3372字 ⁄ 字号 评论关闭

从来没有正经写个文,今天开始要改改了。。

javascript中的继承无非是new 一个函数,称为构造函数,叫什么无所谓,都是函数function,

然后给这个方法的prototype添加一些方法,这些方法我们就说是继承过来的。

javascript中有个概念叫做:“一切皆对象”,就是javascript存在都是对象,

一个对象有2种属性,一种是继承过来的,一种是自己的,

就像大自然的动物一样,从最基础的草履虫到现在的人类,都是一代代的继承扩展,实现丰富多样的世界,javascript的世界也模拟大自然的世界,包括其他语言也类似,软件的世界就是在模拟学习大自然规律。

回到正题,javascript本身语言中没有实现标准的继承方法,

那什么是标准的继承方法呢,就是一个语言中专门用来继承的。

像php中有:

Ancestor{

  //这里面写一大堆方法和属性,私有、共有的等等
   function __construct($options){
          $this->options= $options;
   }
   
  function run(){
        return 1;
  }

};

 

关于上面的语法,不懂的php的可以不用理会了,把上面代码写好之后就可以new 一下Class ,返回了一个对象了,上面的方法和属性可以在对象$obj使用了

$obj = new Ancestor(1);

 

然后继承呢,就是下面这么写

Child extend Ancestor{ 
//里面写一大堆方法属性,可以私有,可以公用等
function __construct($options,$name){
  //执行一下父类的__construct方法
  parent::__construct();
   $this->name= $name;
}
   function run(){
         $num =  parent::__construct();
      return $num +1;

  }

}

$childObj= new Child(1,'一只柯楠');

 

上面的代码就是Child继承Ancestor的方法和属性了。。实例化也是new一下

 

我们可以注意到当Child和Ancestor的方法重复时,我们可以使用parent::方法名来执行父类的方法,这样既可以不覆盖父类的方法,又可以自己扩展一些方法了,很方便。。。

 

关键到了,

javascript中是这样实现的

var Ancestor= function(options){
            this.options= options;

            this.run=function(){
                     return 1;
           }
}    
//实例化Class
var obj= new Ancestor;

//写一个构造方法child
var Child= function(){
      this.run= function(){
          return 2;
     }
}
//让child继承Ancestor
 Child.prototype= new Ancestor; 
var  childObj= new Child(1,'一只柯楠');
//然后给child这里继承之后,Child的run方法肯定会覆盖prototype里面的run方法。

问题来了

1、我们这里没有一个标准方法,先调用父类的重名的方法

2、这样写Child.prototype= new Ancestor;很麻烦,很不规范,对于大项目来说很不统一可能有些人是这样child.prototype.run= function(){}等。。

第一个问题的他解决办法也是有的,不错我个人认为比较搓,即是obj.run.apply(this,arguments);

var Ancestor= function(options){
            this.options= options;

            this.run=function(){
                     return 1;
           }
}    
//实例化Class
var obj= new Ancestor;

//写一个构造方法child
var Child= function(){
      this.run= function(){
          //这里就是先调用父类的run方法,不过你得直接写obj很不友好
          var num = obj.run.apply(this,arguments);
          return num+1;
     }
}
//让child继承Classh
Child.prototype= obj;

var  childObj= new Child(1,'一只柯楠');
//然后给child这里继承之后,Child的run方法肯定会覆盖prototype里面的run方法。

 

 

我们需要一个统一的继承方法解决上面的问题,我已经给大家写了详细的注释,

好吧,

其实写了上面那么多就是为了引出它存在的意义:

(function(win,undefined){
    var initializing = false,
        superTest = /vnice/.test(function () {vnice;}) ? /\b_super\b/ : /.*/;
    this.Class = function () {};

    Class.extend = function (prop) {
        //_super和prototype:new建立一个新的对象,作为新类的prototype,不能直接在上面添加方法,会影响其他使用extend方法返回的类
        var _super = this.prototype;
        //设为true就不再执行init方法
        initializing = true;
        var prototype = new this();
        initializing = false;
        //将传进来的prop对象里的方法拷贝到prototype上面去
        for (var name in prop) {
            prototype[name] = (typeof prop[name] === 'function' && typeof _super[name] === 'function' && superTest.test(prop[name])) ? (function (name, fn) {
            //这一步为了实现,prop里面的某个方法(如prop.init)和原型prototype方法中的方法冲突时,可以在方法中调用【this._super()】,这里将this._super方法替换成原型中的这个方法(prototype.init).
                    return function () {
                        var temp = this._super;    
                        this._super = _super[name];
                        var ret = fn.apply(this, arguments);
                        this._super = temp;
                        return ret;
                    }
                })(name, prop[name]) : prop[name];
        }
        
        function Class () {
            //构造函数中默认调用this.init方法
            if (!initializing && this.init) {
                this.init.apply(this, arguments);
            }
        }
        //让将要返回的类继承prototype
        Class.prototype = prototype;
        //将类的构造函数设为Class
        Class.constructor = Class;
        //将类添加extend方法,方便继续继承
        Class.extend = arguments.callee;
        //返回构造函数
        return Class;
    };
})(window,undefined)    

上面的方法怎么使用呢???

(function(){
//class类的实现
var Ancestor= Class.extend({
      init: function(options){
             this.options= options;
     },
     run: function(){
            return 1;
    }
});
//实例化Class类
var obj= new Ancestor();

var Child= Ancestor.extend({
      init: function(options,name){
         //执行父类的init方法,类似PHP中的parent::init();
          this._super();
          this.name= name
     },

     run: function(){
          var num= this._super();
          return num+1;
     }
});
var  childObj= new Child(1,'一只柯楠');
})()

 

这样就可以生生不息,的继承扩展了。。说的不对的地方欢迎大牛指正。。。

 

 

 

 

抱歉!评论已关闭.