John Resig的Simple JavaScript Inheritance學習__javascript

來源:互聯網
上載者:User
/** * Created by KBWoniu on 16/6/23. * 歡迎批評指正及任何形式的交流! *//** *Simple JavaScript Inheritance * http://ejohn.org/blog/simple-javascript-inheritance/ *//** * 一.繼承的一般方式 * js中沒有類的標準概念,一等公民為函數,我為了理解和分析方便仍然使用類這個概念 * js繼承的方式一般是在建構函式中加入變數定義,然後重新定義它的原型對象prototype為基類的一個執行個體 * function SuperClass(){} //基類 * SuperClass.prototype.someFunc = function(){ *     console.log('SuperClass someFunc'); * }; * * function SubClass() {   //衍生類別 *    //變數定義 *    this.someVal = ''; * } * SubClass.prototype = new SuperClass(); * SubClass.prototype.subFunc = function(){ *     console.log('SubClass subFunc'); * }; * * var sub = new SubClass(); * sub.someFunc();//SuperClass someFunc * sub.subFunc(); //SubClass subFunc * * * 二.解析 * 談一下我的理解: * 1.Class理解為基類 * 2.基類Class提供一個extend方法,通過基類調用該方法可以產生一個新的衍生類別 * 3.指定一個對象,這個對象中包含衍生類別的初始化init(如果必要),和其他的一些擴充方法 * 4.關於衍生類別中的override:可以直接覆蓋;可以在衍生類別中調用基類的方法(必須使用this._super()),並且附加內容 * * 來逐條分析下實現思路。為了達到上述的目的: * 1.定義Class函數,作為基類,直接定義在根環境下 * 2.extend方法作為Class的屬性,而不是執行個體屬性,並且返回一個擴充類,因此,必須返回一個類型。看下他的做法,使用了一個dummy類作為返回 * 3.參數對象 * 4.把衍生類別(dummy類)的prototype賦值為基類的執行個體即可。如何複用基類的方法。這是關鍵所在。定義prototype的衍生類別方法。 * 使用this._super指代基類的方法,作為基類的方法來使用,實際調用時將他替換為基類的方法。這樣,參數對象的方法就更新為了 * 基類+新添加的內容的組合了。他採用的方式是,將基類的原型先儲存到_super變數中,更新prototype對應的方法,該方法使用一個 * 匿名函數重新定義。在重新定義的實現中,先把this._super方法進行了替換,替換為基類的方法,之後才真正去調用參數對象的方法。 * 閉包在此起到了舉足輕重的作用:保持基類的原型對象,通過使用匿名函數的立即調用,將參數對象的方法進行了精緻封裝,對於初學js * 的我來說真是歎為觀止。 * 5.prototype有了,派生也就實現了 * * *三.附上代碼注釋 * 原注釋刪掉了,附上的理解,具體使用的例子就不再贅述了 *//* Simple JavaScript Inheritance * By John Resig http://ejohn.org/ * MIT Licensed. */(function(){  //測試下Regex,得到一個_super的Regex對象,以檢查是否使用了基類的方法  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;  //基類  this.Class = function(){};  //extend方法  Class.extend = function(prop) {    //儲存基類的原型,這個this就是基類類型,就是函數的名稱    var _super = this.prototype;    //定義一個基類的執行個體,為了給衍生類別的prototype用,直接跳過了init方法,init方法可以理解為各個類私人的方法,並且不用於派生    initializing = true;    var prototype = new this();    initializing = false;    //對prototype屬性的重新賦值    for (var name in prop) {      prototype[name] = typeof prop[name] == "function" && //必須是函數        typeof _super[name] == "function" && fnTest.test(prop[name]) ? //必須是使用了_super方法        (function(name, fn){          return function() {            //儲存原對象            var tmp = this._super;            //增加一個_super方法,並且賦值為基類的方法            this._super = _super[name];            //真正調用衍生類別方法,衍生類別方法中的this._super剛剛已經更新為了基類的方法            var ret = fn.apply(this, arguments);            //restore            this._super = tmp;            //傳回值仍然是派生的調用傳回值            return ret;          };        })(name, prop[name]) :        prop[name];//條件陳述式    }    //dummy類    function Class() {      // All construction is actually done in the init method      if ( !initializing && this.init )        this.init.apply(this, arguments);    }    //更新prototype    Class.prototype = prototype;    //因為上面這句會讓它找不到constructior    Class.prototype.constructor = Class;    //沒錯,它也是有extend方法的    Class.extend = arguments.callee;    //返回了衍生類別    return Class;  };})();
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.