日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

MooTools Class 使用、继承详解

發(fā)布時(shí)間:2025/3/17 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MooTools Class 使用、继承详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?? 首先需要說(shuō)明的是,本文將直接講解創(chuàng)建和使用類(lèi)的各種技巧,一些基礎(chǔ)的東西不再做解釋,要理解如何在JavaScript中實(shí)現(xiàn)面向?qū)ο蟮脑O(shè)計(jì),請(qǐng)先參考《JavaScript.高級(jí)程序設(shè)計(jì)(第2版)》(前7章)、《javascript.設(shè)計(jì)模式》(前四章)、《JavaScript.語(yǔ)言精粹》這三部經(jīng)典之作。

? 在Mootools中使用Class構(gòu)造函數(shù)創(chuàng)建一個(gè)類(lèi)有兩種方式,也就是傳遞兩種不同類(lèi)型的參數(shù)給構(gòu)造函數(shù),第一種也是標(biāo)準(zhǔn)方式傳遞一個(gè)對(duì)象字面量,這個(gè)對(duì)象字面量可以包括你為類(lèi)添加的所有屬性、方法。例如:
  • var?Person?=?new?Class({?
  • ????//?Methods?
  • ????initialize:?function?(name,?age)?{?
  • ????????this.name?=?name;?
  • ????????this.age?=?age;?
  • ????},?
  • ?
  • ????log:?function?()?{?
  • ????????console.log(this.name?+?','?+?this.age);?
  • ????}?
  • });?
  • ?
  • var?mark?=?new?Person('mark',?24);?
  • mark.log();?//?returns?'mark,24'?
  • ? 第二種是傳遞一個(gè)普通函數(shù),mootools會(huì)自動(dòng)把這個(gè)函數(shù)包裝成只含一個(gè)initialize鍵值的對(duì)象字面量,然后你可以使用implement方法對(duì)類(lèi)進(jìn)行擴(kuò)展,例如:
  • var?Person?=?new?Class(function?(name,?age)?{?
  • ????this.name?=?name;?
  • ????this.age?=?age;?
  • });?
  • Person.implement('log',?function?()?{?
  • ????console.log(this.name?+?','?+?this.age);?
  • });?
  • var?mark?=?new?Person('mark',?24);?
  • mark.log();?//?returns?'mark,24'?
  • ? 當(dāng)然推薦使用的還是第一種方式,直觀明了嘛。你如果使用標(biāo)準(zhǔn)方式建立了一個(gè)類(lèi),也是可以使用implement方法對(duì)類(lèi)進(jìn)行擴(kuò)展的,如果你真的認(rèn)為有必要把一個(gè)類(lèi)的設(shè)計(jì)拆成幾個(gè)部分的話(例如在使用摻元對(duì)象實(shí)現(xiàn)多親繼承時(shí),神馬?等等...這個(gè)MooTools里實(shí)現(xiàn)多親繼承繼承不是使用Implements Mutator嗎,嗯吶,這個(gè)在接下來(lái)類(lèi)的繼承中將詳細(xì)講解......),呵呵,至于MooTools內(nèi)部如果對(duì)構(gòu)造函數(shù)進(jìn)行解析,有興趣的可看看MooTools 1.4 源碼分析 - Class 修正版。 ? Implement and Extend ? Implement方法用來(lái)為類(lèi)添加新的方法、屬性。需要注意的是,如果新添加的方法或?qū)傩耘c類(lèi)中舊有的方法或?qū)傩酝?#xff0c;則會(huì)覆蓋類(lèi)中舊有的方法、屬性。調(diào)用Implement方法有兩種方式,第一種方式傳遞兩個(gè)參數(shù),第一個(gè)參數(shù)為String類(lèi)型,存儲(chǔ)要添加的方法或?qū)傩缘拿Q,第二個(gè)參數(shù)為方法所對(duì)應(yīng)的函數(shù)或?qū)傩运鶎?duì)應(yīng)的值,這種方式每次只能為類(lèi)添加一個(gè)方法或?qū)傩?#xff1a;
  • Person.implement('log',?function?()?{?
  • ????console.log(this.name?+?','?+?this.age);?
  • });?
  • Person.implement('city',?'深圳');?
  • ? 第二種方式傳遞一個(gè)對(duì)象字面量參數(shù),把要添加的方法屬性包含在這個(gè)對(duì)象中,一次添加多個(gè)方法、屬性,避免重復(fù)調(diào)用implement:
  • Person.implement({?
  • ????'city':?'深圳',?
  • ????'log':?function?()?{?
  • ????????console.log(this.name?+?','?+?this.age);?
  • ????}?
  • });?
  • ? MooTools關(guān)于Class的官方文檔中只暴露了implement一個(gè)方法,其實(shí)對(duì)類(lèi)本身進(jìn)行操作的還有一個(gè)比較重要的方法extend,這個(gè)方法之所以沒(méi)有出現(xiàn)在Class的文檔中。這是因?yàn)樗皇亲鳛镃lass的特殊方法,而實(shí)際上是Type的方法。它的作用是為類(lèi)創(chuàng)建靜態(tài)成員,靜態(tài)成員關(guān)聯(lián)的是類(lèi)本身,換句話說(shuō),靜態(tài)成員是在類(lèi)的層次上操作,而不是在實(shí)例的層次上操作,每個(gè)靜態(tài)成員都只有一份。調(diào)用extend方法的方式同Implement,也是兩種方式。 ? 簡(jiǎn)單一點(diǎn)講,implement為實(shí)例創(chuàng)建方法和屬性,extend為類(lèi)本身創(chuàng)建方法和變量,請(qǐng)看下面的例子:
  • var?Person?=?new?Class(function?(name,?age)?{?
  • ????this.name?=?name;?
  • ????this.age?=?age;?
  • });?
  • Person.implement({?
  • ????instanceMethod:?function?()?{?
  • ????????console.log('From?an?instance!');?
  • ????}?
  • });?
  • Person.extend({?
  • ????classMethod:?function?()?{?
  • ????????console.log('From?the?class?itself!');?
  • ????}?
  • });?
  • ?
  • var?mark?=?new?Person('mark',?24);?
  • ?
  • console.log(typeOf(mark.instanceMethod));?//?returns?'function'?
  • mark.instanceMethod();?//?returns?'From?an?instance!'?
  • console.log(typeOf(mark.classMethod));?//?returns?'null',說(shuō)明實(shí)例是不能調(diào)用靜態(tài)方法的?
  • ?
  • console.log(typeOf(Person.classMethod));?//?returns?'function'?
  • Person.classMethod();?//?returns?'From?the?class?itself!'?
  • console.log(typeOf(Person.instanceMethod));?//?returns?'null',同樣類(lèi)也不能直接調(diào)用為實(shí)例而創(chuàng)建的方法?
  • ?
  • Person.prototype.instanceMethod();?//?類(lèi)只能通過(guò)這種方式調(diào)用原型上的方法?
  • ? 私有成員 ? 嚴(yán)格來(lái)講,JavaScript中沒(méi)有私有成員的概念,所有對(duì)象的屬性都是共有的。不過(guò),倒是有一個(gè)私有變量的概念,任何在函數(shù)中定義的變量,都可以認(rèn)為是私有變量,因?yàn)椴荒茉诤瘮?shù)的外部訪問(wèn)浙西變量。私有變量包括函數(shù)的參數(shù)、局部變量和在函數(shù)內(nèi)定義的其他函數(shù)。所以我們可以通過(guò)使用閉包來(lái)為類(lèi)制造私有成員:
  • var?Person?=?(function?()?{?
  • ????//?私有變量?
  • ????var?numOfPersons?=?0;?
  • ?
  • ????//?私有方法?
  • ????var?formatName?=?function?(name)?{?
  • ????????return?name.capitalize();?
  • ????};?
  • ?
  • ????return?new?Class({?
  • ????????initialize:?function?(name,?age)?{?
  • ????????????this.name?=?name;?
  • ????????????this.age?=?age;?
  • ????????????numOfPersons++;?
  • ????????},?
  • ?
  • ????????//?公有方法?
  • ????????log:?function?()?{?
  • ????????????console.log(formatName(this.name)?+?','?+?this.age);?
  • ????????},?
  • ?
  • ????????getNumOfPersons:?function?()?{?
  • ????????????return?numOfPersons;?
  • ????????}?
  • ????});?
  • })();?
  • ?
  • var?mark?=?new?Person('mark',?24);?
  • mark.log();?//?returns?'mark,24'?
  • console.log(mark.getNumOfPersons());?//?returns?1?
  • ? 使用這個(gè)模式有一個(gè)好處就是,私有成員在內(nèi)存中只會(huì)存放一份,是由所有實(shí)例共享的,不必為每一個(gè)實(shí)例生成一個(gè)副本。但這也延伸出一個(gè)問(wèn)題,來(lái)看下面的代碼:
  • var?Person?=?(function?()?{?
  • ????//?私有變量?
  • ????var?name?=?'';?
  • ?
  • ????return?new?Class({?
  • ????????initialize:?function?(v1,?v2)?{?
  • ????????????name?=?v1;?
  • ????????????this.age?=?v2;?
  • ????????},?
  • ?
  • ????????getName:?function?()?{?
  • ????????????return?name;?
  • ????????},?
  • ?
  • ????????setName:?function?(value)?{?
  • ????????????name?=?value;?
  • ????????},?
  • ?
  • ????????getAge:?function?()?{?
  • ????????????return?this.age;?
  • ????????},?
  • ?
  • ????????setAge:?function?(value)?{?
  • ????????????this.age?=?value;?
  • ????????}?
  • ????});?
  • })();?
  • ?
  • var?mark?=?new?Person('mark',?24);?
  • console.log(mark.getName());?//?'mark'?
  • mark.setName('grey');?
  • console.log(mark.getName());?//?'grey'?
  • console.log(mark.getAge());?//?24?
  • ?
  • var?john?=?new?Person('john',?18);?
  • console.log(john.getName());?//?'john'?
  • console.log(john.getAge());?//?18?
  • console.log(mark.getName());?//?'john'?
  • console.log(mark.getAge());?//?24?
  • ? 這個(gè)例子中的Person構(gòu)造函數(shù)(這里指initialize)與getName()和setName()方法一樣,都有權(quán)訪問(wèn)私有變量name,在這種模式下,變量name就變成了一個(gè)靜態(tài)的、有所有實(shí)例共享的屬性,也就是說(shuō),在一個(gè)實(shí)例上調(diào)用setName()會(huì)影響所有實(shí)例,結(jié)果就是所有實(shí)例getName()都會(huì)返回相同的值,而age是實(shí)例變量就不存在這個(gè)問(wèn)題。到底是使用實(shí)例變量還是靜態(tài)私有變量,最終還是要視你的需求而定。 ? 當(dāng)然上面這個(gè)問(wèn)題只是針對(duì)私有變量的,私有方法就不存在這個(gè)問(wèn)題,相比實(shí)例方法會(huì)更有效率(從內(nèi)存占用的意義上來(lái)說(shuō)),應(yīng)為它只會(huì)被創(chuàng)建一份。 ? 使用閉包還帶來(lái)一個(gè)問(wèn)題,多查找作用域鏈中的一個(gè)層次,就會(huì)在一定程度上影響查找的速度(一般情況下可以忽略不計(jì)),魚(yú)與熊掌不可兼得啊...... ? 常量 ? 最簡(jiǎn)單設(shè)置常量的方法是為類(lèi)添加一個(gè)靜態(tài)屬性,然而靜態(tài)屬性是公有的,類(lèi)的使用者可以隨時(shí)改變它的值,這個(gè)樣的操作后果是很?chē)?yán)重的。這里我們可以使用前面介紹的為類(lèi)設(shè)置靜態(tài)私有變量的方式來(lái)模擬常量,然后在實(shí)例方法中只創(chuàng)建取值器方法而不創(chuàng)建賦值器方法。這樣類(lèi)的使用者只能使用暴露出來(lái)的取值器方法來(lái)得到私有變量的值而不能改變它的值。來(lái)看下面的代碼:
  • var?Person?=?(function?()?{?
  • ????//?私有變量?
  • ????var?AGE_UPPER_BOUND?=?32;?
  • ?
  • ????return?new?Class({?
  • ????????initialize:?function?(v1,?v2)?{?
  • ????????????//?...?
  • ????????},?
  • ?
  • ????????getAGEUPPERBOUND:?function?(value)?{?
  • ????????????return?AGE_UPPER_BOUND;?
  • ????????}?
  • ????});?
  • })();?
  • ? 如果需要使用多個(gè)常量,設(shè)置一個(gè)私有的對(duì)象字面量來(lái)存儲(chǔ)這些常量,然后設(shè)置一個(gè)通用的取值器方法來(lái)取得這些常量:
  • var?Person?=?(function?()?{?
  • ????//?私有變量?
  • ????var?constants?=?{?
  • ????????AGE_UPPER_BOUND:?32,?
  • ????????AGE_LOWER_BOUND:?18?
  • ????};?
  • ?
  • ????return?new?Class({?
  • ????????initialize:?function?(v1,?v2)?{?
  • ????????????//?...?
  • ????????},?
  • ?
  • ????????getConstants:?function?(name)?{?
  • ????????????return?constants[name];?
  • ????????}?
  • ????});?
  • })();?
  • ? 繼承 ? 繼承的主要好處表現(xiàn)在代碼的重用方面,通過(guò)建立類(lèi)之間的繼承關(guān)系,有些方法我們只需要定義一次就可以了。同樣,如果需要修改這些方法或排查其中的錯(cuò)誤,那么由于其定義只出現(xiàn)在一個(gè)位置,所以非常有利于節(jié)省時(shí)間和精力。MooTools實(shí)現(xiàn)類(lèi)的繼承有兩種模式:原型式繼承和多親繼承,原型式繼承由內(nèi)建的Extends Mutator來(lái)實(shí)現(xiàn),多親繼承由Implements Mutator或implement方法來(lái)實(shí)現(xiàn)。 ? 原型式繼承這里就不多講了,著重講一下多親繼承。在JavaScript里,因?yàn)橐粋€(gè)對(duì)象只能擁有一個(gè)原型對(duì)象,所以不允許子類(lèi)繼承多個(gè)超類(lèi),不過(guò)我們可以利用多個(gè)摻元類(lèi)(minix class)或摻元對(duì)象對(duì)一個(gè)類(lèi)進(jìn)行擴(kuò)充,這樣類(lèi)的實(shí)例就可以擁有mixin類(lèi)(對(duì)象)中的方法、屬性,所以這實(shí)際上實(shí)現(xiàn)了多繼承的效果。通常mixin類(lèi)(對(duì)象)包含一些通用的方法,大家可以看看MooTools里Class.Extras模塊中三個(gè)mixin類(lèi)的定義(Chain、Events、Options)。 ? 這里還需要注意的的一點(diǎn)是,在派生具有私有成員的的類(lèi)或implement mixin類(lèi)(對(duì)象)時(shí),因?yàn)樵诟割?lèi)(或mixin)中訪問(wèn)這些私有變量的方法是公有的,所以他們也會(huì)被遺傳下來(lái)。所以子類(lèi)可以間接訪問(wèn)父類(lèi)(或mixin)的私有成員,但子類(lèi)自身的實(shí)例方法都不能直接訪問(wèn)這些私有屬性,而且你也不能在子類(lèi)中添加能夠直接訪問(wèn)他們的方法(作用域變量,你想訪問(wèn)也訪問(wèn)不了啦,呵呵)。 ? 首先我們先建立一個(gè)基類(lèi):
  • var?Animal?=?new?Class({?
  • ????initialize:?function?(age)?{?
  • ????????this.age?=?age;?
  • ????}?
  • });?
  • ? 使用Extends Mutator派生一個(gè)子類(lèi):
  • var?Cat?=?new?Class({?
  • ????Extends:?Animal,?
  • ????initialize:?function?(name,?age)?{?
  • ????????this.parent(age);?//?calls?initalize?method?of?Animal?class?
  • ????????this.name?=?name;?
  • ????}?
  • });?
  • ?
  • var?cat?=?new?Cat('Micia',?20);?
  • console.log(cat.name);?//?'Micia'?
  • console.log(cat.age);?//?20?
  • ? 利用Implements Mutator擴(kuò)充一個(gè)類(lèi),首先建立一個(gè)mixin類(lèi):
  • var?Mixin?=?new?Class({?
  • ????getName:?function?()?{?
  • ????????return?this.name;?
  • ????},?
  • ????setName:?function?(value)?{?
  • ????????this.name?=?value?
  • ????}?
  • });?
  • ?
  • var?Cat?=?new?Class({?
  • ????Extends:?Animal,?
  • ????Implements:?Mixin,?
  • ????initialize:?function?(name,?age)?{?
  • ????????this.parent(age);?//?calls?initalize?method?of?Animal?class?
  • ????????this.name?=?name;?
  • ????}?
  • });?
  • ?
  • var?cat?=?new?Cat('Micia',?20);?
  • console.log(cat.name);?//?'Micia'?
  • console.log(cat.age);?//?20?
  • cat.setName('Dog');?
  • console.log(cat.getName());?//?'Dog'?
  • ? 使用implement方法擴(kuò)充一個(gè)類(lèi),首先家里一個(gè)mixin對(duì)象:
  • //?mixin對(duì)象存儲(chǔ)一些通用方法,可以被不同的類(lèi)implement?
  • var?objMixin?=?(function?()?{?
  • ????var?counter?=?0;?
  • ?
  • ????return?{?
  • ????????init:?function?()?{?
  • ????????????counter?+=?1;?
  • ????????},?
  • ????????getCounter:?function?()?{?
  • ????????????return?counter;?
  • ????????},?
  • ????????getAge:?function?()?{?
  • ????????????return?this.age;?
  • ????????},?
  • ????????setAge:?function?(value)?{?
  • ????????????this.age?=?value;?
  • ????????}?
  • ????};?
  • })();?
  • ?
  • var?Cat?=?new?Class({?
  • ????Extends:?Animal,?
  • ????Implements:?Mixin,?
  • ????initialize:?function?(name,?age)?{?
  • ????????this.parent(age);?//?calls?initalize?method?of?Animal?class?
  • ????????this.name?=?name;?
  • ????}?
  • });?
  • Cat.implement(objMixin);?
  • ?
  • var?Dog?=?new?Class({?
  • ????Extends:?Animal,?
  • ????Implements:?Mixin,?
  • ????initialize:?function?(name,?age)?{?
  • ????????this.parent(age);?//?calls?initalize?method?of?Animal?class?
  • ????????this.name?=?name;?
  • ????}?
  • });?
  • Dog.implement(objMixin);?
  • ?
  • var?cat?=?new?Cat('Micia',?20);?
  • console.log(cat.name);?//?'Micia'?
  • console.log(cat.age);?//?20?
  • cat.setName('湯姆');?
  • console.log(cat.getName());?//?'湯姆'?
  • cat.setAge(12);?
  • console.log(cat.getAge());?//?12?
  • //?對(duì)mixin對(duì)象的私有屬性進(jìn)行操作?
  • cat.init();?
  • console.log(cat.getCounter());?//?1?
  • ?
  • var?dog?=?new?Dog('小狗',?6);?
  • console.log(dog.name);?//?'小狗'?
  • console.log(dog.age);?//?6?
  • dog.setName('布魯托');?
  • console.log(dog.getName());?//?'布魯托'?
  • dog.setAge(8);?
  • console.log(cat.getAge());?//?8?
  • //?對(duì)mixin對(duì)象的私有屬性進(jìn)行操作?
  • dog.init();?
  • console.log(dog.getCounter());?//?2?
  • console.log(cat.getCounter());?//?2?
  • ? 大家都看明白了吧,呵呵,不過(guò)通過(guò)上面的代碼我們引申出另外一個(gè)問(wèn)題,注意上面的Cat類(lèi)的設(shè)計(jì),我們首先設(shè)計(jì)了Extends,然后是Implements,再就是Cat類(lèi)本身的方法屬性,MooTools內(nèi)部對(duì)Class構(gòu)造函數(shù)解析時(shí)是按照我們?cè)O(shè)計(jì)時(shí)的順序解析的嗎?答案是按照我們?cè)O(shè)計(jì)時(shí)的順序解釋的。簡(jiǎn)單來(lái)講MooTools通過(guò)for-in對(duì)對(duì)象進(jìn)行枚舉來(lái)遍歷每個(gè)成員進(jìn)行解釋的,等等......那個(gè)ECMAScript最新版對(duì)for-in 語(yǔ)句的遍歷機(jī)制又做了調(diào)整,屬性遍歷的順序是沒(méi)有被規(guī)定的,也就是說(shuō)隨機(jī)的,那么MooTools是怎樣保證按順序解釋的呢?先看下面這段代碼:
  • var?obj?=?{?
  • ????Waa:?"Waa",?
  • ????aa:?'aa',?
  • ????68:?'68',?
  • ????15:?'15',?
  • ????tt:?'tt',?
  • ????'-7':?'-7',?
  • ????_:?"___",?
  • ????online:?true?
  • };?
  • for?(var?k?in?obj)?{?
  • ????console.log(k);?
  • }?
  • ? 把它放在各個(gè)瀏覽器都執(zhí)行一遍,你會(huì)發(fā)現(xiàn)IE、火狐、Safari瀏覽器的JavaScript 解析引擎遵循的是較老的ECMA-262第三版規(guī)范,屬性遍歷順序由屬性構(gòu)建的順序決定,而Chrome、Opera中使用 for-in 語(yǔ)句遍歷對(duì)象屬性時(shí)會(huì)遵循一個(gè)規(guī)律,它們會(huì)先提取所有 key 的 parseFloat 值為非負(fù)整數(shù)的屬性, 然后根據(jù)數(shù)字順序?qū)傩耘判蚴紫缺闅v出來(lái),然后按照對(duì)象定義的順序遍歷余下的所有屬性。其它瀏覽器則完全按照對(duì)象定義的順序遍歷屬性。 ? 這下明白了吧,只要你為類(lèi)設(shè)計(jì)的方法、屬性還有Mutator的名稱不為數(shù)字就可以了(當(dāng)然如果你非要有這樣的嗜好,我也只能@#%&$......)。請(qǐng)看下面的代碼:
  • var?Super?=?new?Class({?
  • ????log:?function?()?{?
  • ????????console.log('Super');?
  • ????}?
  • });?
  • ?
  • var?Mixin?=?new?Class({?
  • ????log:?function?()?{?
  • ????????console.log('Mixin');?
  • ????}?
  • });?
  • ?
  • var?Sub?=?new?Class({?
  • ????Extends:?Super,?
  • ????Implements:?Mixin?
  • });?
  • ?
  • var?obj?=?new?Sub();?
  • obj.log();?//???
  • ? 在這里obj.log()會(huì)返回什么呢?對(duì)了是'Maxin',這里Sub類(lèi)首先繼承了Super類(lèi),Sub的原型實(shí)際就是Super類(lèi)的一個(gè)實(shí)例,Super的log方法也就是成了Sub的原型上的一個(gè)方法,然后執(zhí)行Implements Mutator 為Sub類(lèi)的原型擴(kuò)展了一個(gè)Mixin類(lèi)的實(shí)例上的方法,這時(shí)Mixin類(lèi)實(shí)例上的log方法就覆蓋了Sub類(lèi)原型上原來(lái)的log方法(繼承自Super類(lèi))。 ? 如果把Extends、Implements的順序顛倒一下:
  • var?Sub?=?new?Class({?
  • ????Implements:?Mixin,?
  • ????Extends:?Super?
  • });?
  • ?
  • var?obj?=?new?Sub();?
  • obj.log();?//???
  • ? 這時(shí)obj.log()會(huì)返回什么呢?還是'Maxin'嗎?其實(shí)這里返回的是'Super',Why?前面我們介紹了MooTools對(duì)Class構(gòu)造函數(shù)解析時(shí)是按照我們?cè)O(shè)計(jì)的順序解析的,所以在這里首先執(zhí)行的是Implements Mutator,它首先為Sub類(lèi)的原型擴(kuò)展了一個(gè)Mixin類(lèi)的實(shí)例上的log方法,然后才是對(duì)超類(lèi)Super的繼承,因?yàn)樵贘avaScrpt里每個(gè)對(duì)象只有一個(gè)原型,原型式繼承的原理就是超類(lèi)的一個(gè)實(shí)例賦予子類(lèi)的原型,子類(lèi)原來(lái)的原型這時(shí)會(huì)被超類(lèi)的實(shí)例替換掉,所以這是Sub類(lèi)原型的引用已經(jīng)指向了超類(lèi)的實(shí)例,而他自己的原型對(duì)象這時(shí)被消除了,所以之前從Mixin類(lèi)得來(lái)的那個(gè)log方法,對(duì)不起跟著一起魂飛湮滅了,所以這里返回的是'Super'。 ? 當(dāng)然如果你嫌不過(guò)癮,那就在為Sub類(lèi)添加一個(gè)log方法:
  • var?Sub?=?new?Class({?
  • ????Implements:?Mixin,?
  • ????Extends:?Super,?
  • ?
  • ????log:?function?()?{?
  • ????????console.log('sub');?
  • ????}?
  • });?
  • var?obj?=?new?Sub();?
  • obj.log();?//???
  • ? 你可以把Sub類(lèi)的Implements、Extends、log來(lái)回顛倒一下看看效果,呵呵,再用implement方法在擴(kuò)展一個(gè)試試:
  • var?objMixin?=?{?
  • ????log:?function?()?{?
  • ????????console.log('objMixin');?
  • ????}?
  • };?
  • ?
  • var?Sub?=?new?Class({?
  • ????Implements:?Mixin,?
  • ????Extends:?Super,?
  • ?
  • ????log:?function?()?{?
  • ????????console.log('sub');?
  • ????}?
  • });?
  • Sub.implement(objMixin);?
  • ?
  • var?obj?=?new?Sub();?
  • obj.log();?//???
  • ? 呵呵,別暈掉,一切都是為了把問(wèn)題搞的跟明白不是...... ? 最后不要忘記兩個(gè)重要的方法:parent()和protect(),這里就不多說(shuō)了,在前面的Class源碼分析里有詳細(xì)介紹。 ? 下一篇在詳細(xì)講解一下Mutators。 ? 苦苦的苦瓜 2011-10-07

    轉(zhuǎn)載于:https://blog.51cto.com/hmking/682098

    總結(jié)

    以上是生活随笔為你收集整理的MooTools Class 使用、继承详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。