js多態-淺析

《JavaScript設計模式與開發實踐》上,講到js的多態,我覺得書上的例子還是挺好的,特此總結一下。
多態就是 同一個操作 作用於不同的對象上面,會產生不同的解釋和不同的執行結果。或者說,給不同的對象發送同一個消息的時候,這些對象會根據這個消息分別給出不同的反饋。

主人家裏養了兩隻動物,分別是一隻鴨和一隻雞,當主人向它們出“叫”的命令時,鴨會“嘎嘎嘎”地叫,而雞會“咯咯咯”地叫。這兩隻動物都會以自己的方式來發出叫聲。它們同樣“都是動物,並且可以發出叫聲”,但根據主人的指令,它們會各自發出不同的叫聲。

//有多態思想,但是擴展性差,多來一隻狗,還要改動makeSound函數,易出錯
var makeSound = function( animal ){
    if ( animal instanceof Duck ){
        console.log( '嘎嘎嘎' );
    }else if ( animal instanceof Chicken ){
        console.log( '咯咯咯' );
    }
};
var Duck = function(){};
var Chicken = function(){};
makeSound( new Duck() ); // 嘎嘎嘎
makeSound( new Chicken() ); // 咯咯咯

多態的基本思想就是:將“做什麼” 和與“誰去做、怎麼去做”分離開來;或者說把不變的事物 與 可能改變的事物 分離開來。

在這個故事中,動物都會叫,這是不變的,但是不同類型的動物具體怎麼叫是可變的。把不變的部分隔離出來,把可變的部分封裝起來,這給予了我們擴展程序的能力,程序看起來是可生長的,也是符合開放—封閉原則的,相對於修改代碼來說,僅僅增加代碼就能完成同樣的功能,這顯然優雅和安全得多。

var maskSound = function(animal){
    animal.sound();
}

var Chicken = function(){}
Chicken.prototype.sound=function(){
    console.log('咯咯咯');
}

var Duck = function(){}
Duck.prototype.sound = function(){
    console.log( '嘎嘎嘎' );
};

makeSound( new Duck() ); // 嘎嘎嘎
makeSound( new Chicken() ); // 咯咯咯

擴展:來了一隻狗,會叫的函數不用變,只需添加上狗怎麼叫的代碼就行。

var Dog = function(){}
Dog.prototype.sound = function(){
console.log( '汪汪汪' );
};
makeSound( new Dog() ); // 汪汪汪

JavaScript 對象的多態性是與生俱來的

JavaScript 的變量類型在運行期是可變的。一個 JavaScript 對象,既可以表示 Duck 類型的 對象,又可以表示Chicken 類型的對象,這意味着 JavaScript 對象的多態性是與生俱來的。 這種與生俱來的多態性並不難解釋。

JavaScript 作爲一門動態類型語言,它在編譯時沒有類型 檢查的過程,既沒有檢查創建的對象類型,又沒有檢查傳遞的參數類型。

在上面代碼示例中, 我們既可以往 makeSound 函數裏傳遞 duck 對象當作參數,也可以傳遞 chicken 對象當作參數。 由此可見,某一種動物能否發出叫聲,只取決於它有沒有 makeSound 方法,而不取決於它是否是某種類型的對象,這裏不存在任何程度上的“類型耦合”。這正是我們從上一節的鴨子類型 中領悟的道理。在 JavaScript 中,並不需要諸如向上轉型之類的技術來取得多態的效果。

發佈了171 篇原創文章 · 獲贊 44 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章