色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

javascript框架之繼承機(jī)制(二)

我們來(lái)模仿一下最OO的mootools的繼承機(jī)制。它的類(lèi)都有一個(gè)叫做initialize構(gòu)造方法,這與Java的類(lèi)都有一個(gè)與類(lèi)名同名的構(gòu)造方法一樣的道理。只不過(guò),這些叫initialize或init都是借鑒自Prototype,而Prototype那幫人是Ruby出身。為了區(qū)別mootools那種污染原生方法的做法,我把類(lèi)的構(gòu)造器命名為variant,并且禁止查看構(gòu)造方法(像瀏覽器禁止查看原生對(duì)象的構(gòu)造方法那樣)。

    var variant = function (options){      options = options || {};      var initialize = options.initialize || function(){};      var klass = initialize ;      klass.constructor = arguments.callee;      klass.prototype.constructor = klass;      klass.toString = function(){//禁止查看構(gòu)造方法        return "function variant(){/n    [variant code]/n}"      }      return klass;    };

這是一個(gè)非常簡(jiǎn)單的工廠方法,用于生產(chǎn)類(lèi)的。options就是一屬性包,可能裝有我們的類(lèi)的構(gòu)造方法,我們要做的是把它提取出來(lái),然后輸送出去。

     function factory(a){         a.b = b;         a.c = c;         return a;      }

不過(guò),這就有點(diǎn)像倒?fàn)敚覀儜?yīng)該像水果商,從果農(nóng)收購(gòu)水果回來(lái)包裝一番,才賣(mài)出去。這包裝就是往要生成的類(lèi)添加各種原型方法與類(lèi)方法。我們進(jìn)一步打造我們的類(lèi)工廠,讓生產(chǎn)的類(lèi)擁有繼承能力,也就是把第一部分的makeBridge 加上去。

prototype繼承是通過(guò)把子類(lèi)的原型設(shè)置成父類(lèi)的一個(gè)實(shí)例來(lái)進(jìn)行繼承的。因此無(wú)論是inherit也好,mixin也好,都是往子類(lèi)的原型添加?xùn)|西。打個(gè)比方,繼承就是把一大堆屬性與方法直接加在子類(lèi)的原型上,mixin則相當(dāng)于把一打?qū)傩耘c方法逐一加到構(gòu)造函數(shù)的原型。不過(guò)在上面Tiger類(lèi)的構(gòu)造器寫(xiě)得有點(diǎn)不好,因?yàn)閚ame屬性本來(lái)父類(lèi)就有,子類(lèi)就不用定義一次。如果父類(lèi)有許多實(shí)例屬性,豈不是要寫(xiě)一大打賦值語(yǔ)句。應(yīng)該改為

    var Tiger = variant({      inherit:Animal,      initialize:function(name,age){        this.superclass(arguments);//this.name = name        this.age =age;      },      getAge : function(){        return this.age;      },      setAge : function(age){        this.age = age;      }    })

但是這種做法在第三代子類(lèi)就行不通了,比如我們弄個(gè)子類(lèi)叫IndiaTiger,它比Tiger多出一個(gè)類(lèi)例屬性location。

var IndiaTiger = variant({        inherit:Tiger,        initialize:function(name,age,location){          this.superclass(arguments);          this.location =location;        }      });

當(dāng)new印度虎實(shí)例時(shí)就報(bào)錯(cuò)了,除非其父類(lèi)的構(gòu)造器沒(méi)有用到this.superclass(arguments)。不用說(shuō),問(wèn)題是出自this,它的不確定性總是為我們?nèi)呛芏嗦闊_@里的this總為IndiaTiger 的實(shí)例,因此this.superclass總為T(mén)iger ,也因此我們無(wú)法實(shí)例化Animal 。Javascript的實(shí)例化過(guò)程是,有父類(lèi)先實(shí)例化父類(lèi),然后再到下級(jí)子類(lèi)。由于我們無(wú)法通過(guò)klass.prototype.superclass獲取Animal,我們可以用klass.superclass來(lái)試一下。klass為類(lèi),而this為實(shí)例:

IndiaTiger.superclass.apply(this, arguments);//this為IndiaTiger 的實(shí)例//arguments為IndiaTiger 構(gòu)造器的參數(shù)對(duì)象

但我們不能把前面的IndiaTiger 寫(xiě)死,因?yàn)閯?chuàng)建IndiaTiger 這個(gè)類(lèi)時(shí),它還不知自己叫IndiaTiger ,我們可以通過(guò)arguments.callee獲取IndiaTiger自身。Tiger的構(gòu)造相仿。

        var IndiaTiger = variant({          inherit:Tiger,          initialize:function(name,age,location){            arguments.callee.superclass.apply(this, arguments);            this.location =location;          }        });

我們可以把它再抽取出來(lái),這樣每次就不用寫(xiě)這么長(zhǎng)的代碼了。

        function _super(o, args) {//o為子類(lèi)的實(shí)例,agrs為子類(lèi)構(gòu)造的arguments對(duì)象            return args.callee.superclass.apply(o, args);        }

上面的代碼已經(jīng)假設(shè)了,它的構(gòu)造器總會(huì)有inherit這個(gè)屬性,但如果沒(méi)有豈不是會(huì)報(bào)錯(cuò),另,它還假設(shè)了我們的類(lèi)上面有一個(gè)屬性叫superclass,因此我們要在類(lèi)工廠中做相應(yīng)的調(diào)整。添加或修改如下兩行代碼:

  var superclass = options.inherit || Object;  klass.superclass = superclass; //類(lèi)的superclass

不過(guò)每次設(shè)置新類(lèi)的構(gòu)造器時(shí)都要添加一行_super(this,arguments)也太麻煩了,最好把它隱藏起來(lái),內(nèi)部調(diào)用。另,把_super方法放到工廠外,顯得太松散,既然也是用來(lái)構(gòu)建類(lèi),因此也該把它整合到類(lèi)工廠中。

      function factory(a){         var b = function(){             s();             a();             //*****其他方法         }         return b      }

也就是說(shuō),我們只要這樣設(shè)置類(lèi)的構(gòu)造器即可:

        var IndiaTiger = Variant({          inherit:Tiger,          initialize:function(name,age,location){            this.location =location;//★★★★★          }        });

it知識(shí)庫(kù)javascript框架之繼承機(jī)制(二),轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 汉寿县| 汉寿县| 和政县| 咸丰县| 大冶市| 大城县| 隆安县| 阿克陶县| 无棣县| 大同市| 敦化市| 道真| 兴城市| 泌阳县| 揭东县| 温宿县| 花垣县| 乾安县| 罗江县| 昌图县| 平阴县| 八宿县| 时尚| 鄂托克前旗| 齐齐哈尔市| 惠水县| 玉屏| 青海省| 轮台县| 南皮县| 莫力| 和龙市| 福州市| 松江区| 台中市| 应城市| 正蓝旗| 曲周县| 樟树市| 江津市| 汾阳市|