亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

介紹一個簡單的JavaScript類框架

2019-11-20 12:10:11
字體:
來源:轉載
供稿:網友

 在寫work-in-progress JavaScript book一書時,對于javascript繼承體系,我花費了相當的時間,并在該過程中研究了各種不同的模擬經典類繼承的方案。這些技術方案中,我最為推崇的是base2與Prototype的實現。

從這些方案中,應該能提煉出一個具有其思想內涵的框架,該框架須具有簡單、可重用、易于理解并無依賴等特點,其中簡單性與可用性是重點。以下是使用示例:
 

var Person = Class. extend ( { init: function (isDancing ) {  this. dancing = isDancing; }, dance: function ( ) {  return this. dancing; }} );var Ninja = Person.extend({ init: function(){  this._super( false ); }, dance: function(){  // Call the inherited version of dance()  return this._super(); }, swingSword: function(){  return true; }});var p = new Person(true);p.dance(); // => truevar n = new Ninja();n.dance(); // => falsen.swingSword(); // => true// Should all be truep instanceof Person && p instanceof Class &&n instanceof Ninja && n instanceof Person && n instanceof Class

 

有幾點需要留意:

  •     構造函數須簡單(通過init函數來實現),
  •     新定義的類比須繼承于已有的類,
  •     所有的‘類'都繼承于始祖類:Class,因此如果要創建一個全新的類,該類必須為Class的子類,
  •     最具挑戰的一點:父類的被覆寫方法必須能訪問到(通過配置上下文環境)。
  •     在上面的示例中,你能發現通過this._super()來調用Person父類的init()和dance()方法。

對結果相當滿意:使類的定義結構化,保持單一繼承,并且能夠調用超類方法。

簡單的類創建與繼承

下面為其實現(便于閱讀并有注釋),大概25行左右。歡迎并感謝提出建議。
 

/* Simple JavaScript Inheritance * By John Resig http://ejohn.org/ * MIT Licensed. */// Inspired by base2 and Prototype( function ( ) { var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? //b_super/b/ : /.*/; // The base Class implementation (does nothing) this.Class = function(){};   // Create a new Class that inherits from this class Class.extend = function(prop) {  var _super = this.prototype;     // Instantiate a base class (but only create the instance,  // don't run the init constructor)  initializing = true;  var prototype = new this();  initializing = false;     // Copy the properties over onto the new prototype  for (var name in prop) {   // Check if we're overwriting an existing function   prototype[name] = typeof prop[name] == "function" &&    typeof _super[name] == "function" && fnTest.test(prop[name]) ?    (function(name, fn){     return function() {      var tmp = this._super;             // Add a new ._super() method that is the same method      // but on the super-class      this._super = _super[name];             // The method only need to be bound temporarily, so we      // remove it when we're done executing      var ret = fn.apply(this, arguments);          this._super = tmp;             return ret;     };    })(name, prop[name]) :    prop[name];  }     // The dummy class constructor  function Class() {   // All construction is actually done in the init method   if ( !initializing && this.init )    this.init.apply(this, arguments);  }     // Populate our constructed prototype object  Class.prototype = prototype;     // Enforce the constructor to be what we expect  Class.prototype.constructor = Class;  // And make this class extendable  Class.extend = arguments.callee;     return Class; };})();

其中  “初始化(initializing/don't call init)”與“創建_super方法”最為棘手。接下來,我會對此做簡要的介紹,使得大家對其實現機制能更好的理解。

初始化

    為了說明函數原型式的繼承方式,首先來看傳統的實現過程,即將子類的prototype屬性指向父類的一個實例。如下所示:

 

function Person ( ) { }function Ninja ( ) { }Ninja. prototype = new Person ( );// Allows for instanceof to work:(new Ninja()) instanceof Person

然而,這里具有挑戰性的一點,便是我們只想要得到‘是否實例(instatnceOf)'的效果,而不需要實例一個 Person并調用其構造函數所帶來的后果。為防止這一點,在代碼中設置一個bool參數initializing,只有在實例化父類并將其配置到子類的prototype屬性時, 其值才為true。這樣處理的目的是區分開真正的實例化與設計繼承時這兩種調用構造函數之間的區別,進而在真正實例化時調用init方法:
 

if ( !initializing ) this.init.apply(this, arguments);

    值得特別注意的是,因為在init函數中可能會運行相當費資源的代碼(如連接服務器,創建DOM元素等,誰也無法預測),所以做出區分是完全必要的。

超類方法(Super Method)

當使用繼承時,最常見的需求便是子類能訪問超類被覆寫的方法。在該實現下,最終的方案便是提供一個臨時方法(._super),該方法指向超類方法,并且只能在子類方法中訪問。
 

var Person = Class. extend ( { init: function (isDancing ) {  this. dancing = isDancing; }} );var Ninja = Person.extend({ init: function(){  this._super( false ); }});var p = new Person(true);p.dancing; // => truevar n = new Ninja();n.dancing; // => false


實現這一功能需要幾步處理。首先,我們使用extend來合并基本的Person實例(類實例,上面我們提到過其構造過程)與字面對象(Person.extend()的函數參數)。在合并過程中,做了簡單的檢查:首先檢查將被合并的的屬性是否為函數,如為函數,然后檢查將被覆寫的超類屬性是否也為函數?如果這兩個檢查都為true,則需要為該屬性準備_super方法。

注意,在這里創建了一個匿名閉包(返回的是函數對象)來封裝增加的super方法。基于維護運行環境的需要,我們應該將舊的this._super(不管其是否存在)保存起來以備函數運行后重置,這有助于在有相同名稱(不想偶然丟失對象指針)的情況下發生不可預知的問題。

然后,創建新的_super方法,該方法對象僅指向超類中被覆寫的方法。謝天謝地,不用對_super做任何改動或變更作用域,因為函數的執行環境會隨著函數調用對象自動變更(指針this會指向超類).

最后,調用字面量對象的方法,方法執行中可能會使用this._super(),方法執行后,將屬性_super重置回其原來狀態,之后return退出函數。


以上可以有許多種方案能達到相同的效果(我之前曾見過將super綁定到其自身,然后用arguments.callee訪問),但是感覺還是這種方法最能能體現可用性與簡潔性的特點。

在我已完成的多個基于javascript原型的工作中,只有這個類繼承實現方案是我發表出來與大家分享的。我認為,簡潔的代碼(易于學習,易于繼承,更少下載)更需要提出來讓大家探討,因此,對于學習javascript類構造與繼承的人們來說,這套實現方案是一個好的開始。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品电影久久久| 国产成人aa精品一区在线播放| 亚洲一区二区三区视频| 日韩在线视频免费观看高清中文| 久久视频中文字幕| 色天天综合狠狠色| 欧美日韩999| 久久精品2019中文字幕| 日韩精品欧美激情| 亚洲欧美国产精品| 国产91在线高潮白浆在线观看| 久久深夜福利免费观看| 久久视频在线播放| 久久精品国产欧美亚洲人人爽| 亚洲曰本av电影| 91在线精品播放| 久久精品视频网站| 精品av在线播放| 日本欧美国产在线| 中文字幕免费精品一区| 亚洲一区二区黄| 国产精品a久久久久久| 国产成人一区二区三区电影| 亚洲国产日韩一区| 国产日韩欧美影视| 精品久久久久久久久久久久| 国产精品h片在线播放| 美女精品久久久| 日韩美女视频中文字幕| 美女啪啪无遮挡免费久久网站| 91av在线免费观看视频| 精品国模在线视频| 成人在线视频网站| 伊人亚洲福利一区二区三区| 亚洲综合最新在线| 欧美性xxxx极品hd欧美风情| 中文字幕亚洲一区在线观看| 色多多国产成人永久免费网站| 国产欧美在线播放| 国产精品毛片a∨一区二区三区|国| 久久久久久久久久久国产| 午夜精品三级视频福利| 另类天堂视频在线观看| 日韩欧美中文第一页| 亚洲精品一区中文字幕乱码| 国产精品永久在线| 欧美成人精品在线| 精品欧美激情精品一区| 日韩电影免费观看在线| 久久久久久久色| 91人人爽人人爽人人精88v| 日韩精品中文字幕久久臀| 青青青国产精品一区二区| 欧美黑人一级爽快片淫片高清| 国产亚洲免费的视频看| 欧美视频一二三| 亚洲美女av在线| 国产日韩中文在线| 精品免费在线视频| 国产精品久久中文| 精品亚洲一区二区三区| 国模精品视频一区二区| 一区二区三区视频在线| 国产在线观看精品一区二区三区| 亚洲在线一区二区| 精品久久久久久久久久久久久| 久久手机免费视频| 97超碰国产精品女人人人爽| 96精品久久久久中文字幕| 成人午夜在线视频一区| 久久久久久国产三级电影| 欧美精品免费在线| 久久久久久久国产精品| 精品视频一区在线视频| 不卡av在线播放| 日本成熟性欧美| 日本久久久a级免费| 久久夜色撩人精品| 久久亚洲电影天堂| 最近2019年手机中文字幕| 色噜噜久久综合伊人一本| zzijzzij亚洲日本成熟少妇| 日韩有码片在线观看| 97精品视频在线观看| 欧美国产第二页| 热久久这里只有精品| 欧美日韩国产在线看| 一本一道久久a久久精品逆3p| 亚洲精品视频播放| 久久久久久久成人| 欧美日韩性视频在线| 一区二区三区视频在线| 日韩精品视频在线观看免费| 日韩亚洲欧美中文高清在线| 亚洲一区二区在线播放| 欧美大尺度在线观看| 欧美国产精品va在线观看| 成人欧美一区二区三区黑人| 国产日本欧美一区二区三区| 国产精品白嫩美女在线观看| 97视频在线观看免费| 国产欧美一区二区三区久久| 亚洲国产天堂久久国产91| 国产日韩精品在线观看| 热久久视久久精品18亚洲精品| 国产91精品不卡视频| 在线观看视频亚洲| 91久久久久久久一区二区| 高潮白浆女日韩av免费看| 亚洲人成电影网| 欧美大成色www永久网站婷| 亚洲精品国产精品国自产观看浪潮| 久久九九全国免费精品观看| 91亚洲va在线va天堂va国| 日韩免费视频在线观看| 狠狠色噜噜狠狠狠狠97| 久久精品最新地址| 国产成人97精品免费看片| 国产91在线播放九色快色| 国产日韩欧美黄色| 亚洲成人黄色网址| 亚洲国产精品一区二区三区| 欧美大荫蒂xxx| 狠狠躁夜夜躁人人爽超碰91| 精品久久久91| 国产成人精品免高潮费视频| 亚洲午夜色婷婷在线| 欧美激情国内偷拍| 狠狠爱在线视频一区| 两个人的视频www国产精品| 日韩成人中文电影| www.久久色.com| 97在线看免费观看视频在线观看| 日韩亚洲欧美中文高清在线| 日韩久久免费电影| 亚洲视频第一页| 国产精品18久久久久久麻辣| 国产精品观看在线亚洲人成网| 久久精品中文字幕电影| 久久九九热免费视频| 伊人伊成久久人综合网小说| 青青草国产精品一区二区| 高清欧美一区二区三区| 欧美激情在线狂野欧美精品| 91精品综合久久久久久五月天| 国产精品视频专区| 欧美性xxxxxx| 欧美激情精品久久久久久大尺度| 国产精品一区二区久久久| 欧美日韩亚洲成人| 中文字幕亚洲欧美一区二区三区| 亚洲精品欧美极品| 欧美日韩在线一区| 91久久精品久久国产性色也91| 91久久精品日日躁夜夜躁国产| 国产在线精品自拍| 亚洲女性裸体视频| 亚洲欧美资源在线| 精品国产乱码久久久久久天美| 在线观看日韩专区| 欧美精品在线第一页| 欧美丰满老妇厨房牲生活| 中文字幕在线成人| 欧美亚洲另类激情另类|