javascript中最好用的extend繼承方法

來源:互聯網
上載者:User

從來沒有正經寫個文,今天開始要改改了。。

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;           }}    //執行個體化Classvar obj= new Ancestor;//寫一個構造方法childvar 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;           }}    //執行個體化Classvar obj= new Ancestor;//寫一個構造方法childvar Child= function(){      this.run= function(){          //這裡就是先調用父類的run方法,不過你得直接寫obj很不友好          var num = obj.run.apply(this,arguments); return num+1;     }}//讓child繼承ClasshChild.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,'一隻柯楠');})()

 

這樣就可以生生不息,的繼承擴充了。。說的不對的地方歡迎大牛指正。。。

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.