第一章 面向?qū)ο蟮腏avaScript

前言


《JavaScript設(shè)計模式與開發(fā)實踐》是由騰訊的前端團(tuán)隊Alloy Team出品的一本關(guān)于js設(shè)計模式的書籍绪励。全書主要分為3大部分:基礎(chǔ)知識、設(shè)計模式和設(shè)計原則和編程技巧疏魏⊥W觯基礎(chǔ)知識主要是介紹了js語言的面向?qū)ο笏枷搿⒍鄳B(tài)大莫、封裝蛉腌、原型、閉包、高階函數(shù)等烙丛;設(shè)計模式以沒中模式一個章節(jié)介紹了16種經(jīng)常在js開發(fā)中用的設(shè)計模式舅巷;設(shè)計原則和編程技巧,從新的高度講解常用到的開發(fā)和設(shè)計技巧河咽。

本文主要基于全書第一部分: js基礎(chǔ)知識的閱讀經(jīng)驗钠右,進(jìn)行總結(jié)。

動態(tài)語言和鴨子類型

靜態(tài)語法: 一種需要進(jìn)行編譯的語言忘蟹,其在編譯時決定了數(shù)據(jù)的類型飒房,同時在編譯時能夠發(fā)現(xiàn)程序中的錯誤。它能夠讓程序員按照相應(yīng)的約束進(jìn)行開發(fā)媚值,但是會在一定程度上降低開發(fā)效率狠毯。

動態(tài)語言:運行時才能決定數(shù)據(jù)的類型。編碼簡潔褥芒,程序員可以把更多的精力放到邏輯實現(xiàn)上去嚼松。

鴨子模型: 走起路來想鴨子,叫起來像鴨子锰扶,那么它就是鴨子惜颇。 鴨子模型知道我們只關(guān)注對象的行為,而不是關(guān)注對象本身少辣,也就是關(guān)注has-a凌摄,而不是is-a。

鴨子模型可以指導(dǎo)我們在動態(tài)語言中實現(xiàn)一個原則:面向接口編程而不是面向?qū)崿F(xiàn)編程漓帅。如:一個對象如有push和pop方法锨亏,并且這些方法提供了正確的實現(xiàn),它就可以當(dāng)做棧來使用忙干。在靜態(tài)語言中器予,面向接口編程是一件不容易的事情,需要通過抽象類型獎對象向上轉(zhuǎn)型(java里的interface?)捐迫。

多態(tài)

多態(tài)的主旨思想是: 把“做什么”和“誰去做以及怎么做”分離開乾翔,也就是將“不變的事情”和“可能變的事情”分離開。如下面的例子:

    var makeSound = function(animal){
        if(animal instanceof Duck){
            console.log("嘎嘎嘎");
        }else if(animal instanceof Chikcen){
            console.log("咯咯咯");
        }
    };
    var Duck = function(){};
    var Chicken = function(){};
    
    makeSound(new Duck());
    makeSound(new Chicken());
    

上述代碼中沒有把不變的事情(動物會叫)和可能變得事情(不同動物以及不不同動物的叫聲)區(qū)分開來施戴,如果加以區(qū)分反浓,就會成為下面的樣子:

    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());

這樣以后才增加新的動物時就可以只關(guān)注變化的東西,而不要在去處理不要變化的東西了赞哗,如增加狗叫:

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

靜態(tài)語言(如java)實現(xiàn)多態(tài)的基本思想是基類定義此方法雷则,然后子類給以不同的實現(xiàn),在進(jìn)行調(diào)用時通過對象的多態(tài)實現(xiàn)方法的調(diào)用肪笋。

總結(jié)起來: 多態(tài)最根本的作用就是通過把過程化的條件分支語句轉(zhuǎn)成對象的多態(tài)性月劈,從而消除這些條件分支語句度迂;它時刻在提醒我們做什么和怎么去做是可一個分開的。

在設(shè)計模式中猜揪,命令模式惭墓、組合模式以及策略模式都是多態(tài)的典型代表,這些可以在后續(xù)的文章中講述而姐。

封裝

封裝可以分為:封裝數(shù)據(jù)诅妹、封裝實現(xiàn)、封裝數(shù)據(jù)和封裝變化毅人。

封裝數(shù)據(jù)主要體現(xiàn)在局部作用域吭狡,對外隱藏,如下面的代碼段:

    js:
    var myObj = function(){
        var name = "ahu";
        return {
            getName: function(){
                return name;
            }
        }
    }
    console.log(myObj.name) // undefined
    console.log(myObj.getName()) // ahu
    
    java:
    public Class myObj{
        private name;
        public myObj(name){
            this.name = name;
        }
        public getName(){
            return name;
        }
    }
    
    myObj nameInfo = new myObj("ahu");
    nameInfo.getName() // ahu

封裝實現(xiàn):對象對它自己的行為負(fù)責(zé)丈莺,其他對象或者用戶不關(guān)心它的內(nèi)部實現(xiàn)划煮。這樣使得對象之間的耦合松散,對象之間通過暴露的API接口進(jìn)行通信缔俄。例如迭代器方法(js中的each方法)弛秋,它負(fù)責(zé)遍歷對象,其內(nèi)部實現(xiàn)改變了俐载,但只要功能不變蟹略,對用戶來說都是不變的。

封裝類型: 封裝類型是通過抽象類和接口來實現(xiàn)的遏佣,如:java的多態(tài)

封裝變化: 找到變化并封裝之是《設(shè)計模式》的出發(fā)點挖炬,23種的設(shè)計模式被劃分為:創(chuàng)建型模式、結(jié)構(gòu)性模式和行為型模式状婶。創(chuàng)建型模式的目的是封裝創(chuàng)建對象的變化意敛;結(jié)構(gòu)型模式封裝的是對象之間的組合關(guān)系;行為型模式封裝的是對象的行為變化膛虫。

原型模式(繼承)

原型模式在設(shè)計模式上來看草姻,是一種創(chuàng)建對象的模式。原型模式很大程序上是基于clone來實現(xiàn)的稍刀,clone是創(chuàng)建對象的一種手段撩独。 如ECMAScript5中提供了Object.create實現(xiàn)對象的clone,不支持此方法的瀏覽器可以用下面的方法進(jìn)行兼容:

    Objcet.create = Object.create || function(_obj){
        var F = function(){};
        F.prototype = _obj;
        return new F();
    }

js中的原型繼承账月,其遵循以下基本原則:

  • 所有的數(shù)據(jù)都是對象(其實js此處實現(xiàn)并不好综膀,基礎(chǔ)類型number、string捶障、boolean僧须、undefined需要進(jìn)行封裝才能得到對象)
  • 要得到一個對象,不是通過實例化類项炼,而是找到一個對象作為原型并clone它
  • 對象會記住它的原型(proto屬性指向了構(gòu)造函數(shù)的constructor)
  • 如果對象無法響應(yīng)某個請求担平,它會把這個請求委托給它自己的原型(原形鏈搜索)

如下程序:

    function person(name){ // person不是類 而是一個構(gòu)造器 js中的函數(shù),既可以作為普通函數(shù)調(diào)用锭部,也可以作為構(gòu)造器調(diào)用
        this.name = name;
    }
    Person.prototype.getName = function(){
        return this.name;
    }
    
    var aa = new Person("ahu") // new時 此時函數(shù)是一個構(gòu)造器
    
    // new操作和一下過程是等同的
    var ObjectFactory = function(){
        var obj = new Object(), // 從Object.prototype上clone一個空的對象
        Constructor = [].shift(call).agruments; // 獲得構(gòu)造器暂论,如上面的Person
        obj.__proto__ = ConStructor.prototype; // 指向正確的原型, 這也是在一些框架中經(jīng)常出現(xiàn):AA.prototype.constructor = AA 的修正
        var ret = Constructor.apply(obj, arguments); // 確保構(gòu)造器總是返回一個對象
        
        return  typeof ret === 'object' ?ret :obj;
    }
    
    var bb = ObjectFactory(person, "ahu");
    console.log(Object.getPrototypeOf(a) === Person.prototype);  // true

套用Peter Norving的一句話:設(shè)計模式是對語言不足的補充, 如果要是有設(shè)計模式拌禾, 不如去找一門更好的語言取胎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市湃窍,隨后出現(xiàn)的幾起案子闻蛀,更是在濱河造成了極大的恐慌,老刑警劉巖您市,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觉痛,死亡現(xiàn)場離奇詭異,居然都是意外死亡茵休,警方通過查閱死者的電腦和手機薪棒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榕莺,“玉大人俐芯,你說我怎么就攤上這事《ぱ欤” “怎么了吧史?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長唠雕。 經(jīng)常有香客問我扣蜻,道長,這世上最難降的妖魔是什么及塘? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任莽使,我火速辦了婚禮,結(jié)果婚禮上笙僚,老公的妹妹穿的比我還像新娘芳肌。我一直安慰自己,他們只是感情好肋层,可當(dāng)我...
    茶點故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布亿笤。 她就那樣靜靜地躺著,像睡著了一般栋猖。 火紅的嫁衣襯著肌膚如雪净薛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天蒲拉,我揣著相機與錄音肃拜,去河邊找鬼痴腌。 笑死,一個胖子當(dāng)著我的面吹牛燃领,可吹牛的內(nèi)容都是我干的士聪。 我是一名探鬼主播,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼猛蔽,長吁一口氣:“原來是場噩夢啊……” “哼剥悟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起曼库,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤区岗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毁枯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慈缔,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年后众,在試婚紗的時候發(fā)現(xiàn)自己被綠了胀糜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒂誉,死狀恐怖教藻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情右锨,我是刑警寧澤括堤,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站绍移,受9級特大地震影響悄窃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹂窖,卻給世界環(huán)境...
    茶點故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一轧抗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞬测,春花似錦横媚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孝宗,卻和暖如春穷躁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背因妇。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工问潭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猿诸,地道東北人。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓睦授,卻偏偏與公主長得像两芳,于是被迫代替她去往敵國和親摔寨。 傳聞我的和親對象是個殘疾皇子去枷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容