《JavaScript設計模式與開發實踐》筆記第一章

第一章 面向對象的JavaScript

  1. 動態類型語言和鴨子類型
    • 編程語言按照數據類型大體可以分爲兩類:靜態類型語言、動態類型語言。
    • 靜態類型語言:在編譯時便已確定變量的類型。
      • 優點:
        1. 在編譯時就能發現類型不匹配的錯誤。
        2. 在程序中明確地規定了數據類型,編譯器還可以針對這些信息對程序進行一些優化工作,提高程序執行速度。
      • 缺點:類型的聲明也會增加更多的代碼,會讓程序員的精力從思考業務邏輯上分散開來。
    • 動態類型語言:變量類型要到程序運行的時候,待變量被賦予某個值之後,纔會具有某種類型。
      • 優點:
        1. 編寫的代碼數量更少,看起來也更加簡潔,程序員可以把精力更多地放在業務邏輯上面。
        2. 編碼靈活。
      • 缺點:無法保證變量的類型,從而在程序的運行期有可能發生跟類型相關的錯誤。
    • JavaScript是一門典型的動態類型語言。
    • 鴨子類型:如果它走起路來像鴨子,叫起來也是鴨子,那麼它就是鴨子。
  2. 多態:同一操作作用於不同的對象上面,可以產生不同的解釋和不同的執行結果。
    • 多態JavaScript例子:
     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 makeSound = function (animal) {
         animal.sound();
     };
     var Duck = function () {}
     Duck.prototype.sound = function () {
         console.log('嘎嘎嘎');
     };
     var Chicken = function () {}
     Chicken.prototype.sound = function () {
         console.log('咯咯咯');
     };
     makeSound(new Duck()); // 嘎嘎嘎
     makeSound(new Chicken()); // 咯咯咯
    • 類型檢查和多態:在靜態類型語言中編譯時會進行類型匹配檢查,不能給變量賦予不同類型的值所以需要向上轉型(當給一個類變量賦值時,這個變量的類型既可以使用這個類本身,也可以使用這個類的超類)。
    • 使用繼承得到多態效果
      • 繼承通常包括實現繼承和接口繼承。
      • 實現繼承例子:
        先創建一個Animal 抽象類,再分別讓Duck 和Chicken 都繼承自Animal 抽象類
        public abstract class Animal {
            abstract void makeSound(); // 抽象方法
        }
        public class Chicken extends Animal {
            public void makeSound() {
                System.out.println("咯咯咯");
            }
        }
        public class Duck extends Animal {
            public void makeSound() {
                System.out.println("嘎嘎嘎");
            }
        }
        Animal duck = new Duck(); // (1)
        Animal chicken = new Chicken(); // (2)
        public class AnimalSound {
            public void makeSound(Animal animal) { // 接受Animal 類型的參數
                animal.makeSound();
            }
        }
        public class Test {
            public static void main(String args[]) {
                AnimalSound animalSound = new AnimalSound();
                Animal duck = new Duck();
                Animal chicken = new Chicken();
                animalSound.makeSound(duck); // 輸出嘎嘎嘎
                animalSound.makeSound(chicken); // 輸出咯咯咯
            }
        }
    • JavaScript的多態
      • 多態的思想實際上是把“做什麼”和“誰去做”分離開來。
      • 在JavaScript 中,並不需要諸如向上轉型之類的技術來取得多態的效果。
    • 多態在面向對象程序設計中的作用
      • 《重構:改善既有代碼的設計》裏寫到:多態的最根本好處在於,你不必再向對象詢問“你是什麼類型”而後根據得到的答案調用對象的某個行爲——你只管調用該行爲就是了,其他的一切多態機制都會爲你安排妥當。
      • 多態最根本的作用就是通過把過程化的條件分支語句轉化爲對象的多態性,從而消除這些條件分支語句。
      • 地圖應用例子:
        var googleMap = {
            show: function () {
                console.log('開始渲染谷歌地圖');
            }
        };
        var baiduMap = {
            show: function () {
                console.log('開始渲染百度地圖');
            }
        };
        var renderMap = function (map) {
            if (map.show instanceof Function) {
                map.show();
            }
        };
        renderMap('google'); // 輸出:開始渲染谷歌地圖
        renderMap('baidu'); // 輸出:開始渲染百度地圖
    • 封裝:封裝的目的是將信息隱藏
      • 封裝數據:JavaScript 並沒有提供對這些關鍵字的支持,我們只能依賴變量的作用域來實現封裝特性,而且只能模擬出public 和private 這兩種封裝性。例子:
        var myObject = (function () {
        var __name = 'sven'; // 私有(private)變量
        return {
            getName: function () { // 公開(public)方法
                return __name;
            }
          }
        })();
        console.log(myObject.getName()); // 輸出:sven
        console.log(myObject.__name) // 輸出:undefined
      • 封裝類型:封裝類型是通過抽象類和接口來進行的。把對象的真正類型隱藏在抽象類或者接口之後,JavaScript 中,並沒有對抽象類和接口的支持。
      • 封裝變化:封裝在更重要的層面體現爲封裝變化,《設計模式》一書曾提到如下文字,“考慮你的設計中哪些地方可能變化,這種方式與關注會導致重新設計的原因相反。它不是考慮什麼時候會迫使你的設計改變,而是考慮你怎樣才能夠在不重新設計的情況下進行改變。這裏的關鍵在於封裝發生變化的概念,這是許多設計模式的主題。”
    • 原型模式和基於原型繼承的JavaScript對象系統:JavaScript 也同樣遵守這些原型編程的基本規則
      • 所有的數據都是對象
        1. 基本類型包括undefined、number、boolean、string、function、object。
        2. JavaScript 中的根對象是Object.prototype 對象,Object.prototype 對象是一個空的對象。
      • 要得到一個對象,不是通過實例化類,而是找到一個對象作爲原型並克隆它。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章