国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript設(shè)計模式與開發(fā)實踐 | 01 - 面向?qū)ο蟮腏avaScript

suxier / 1597人閱讀

摘要:在中,并沒有對抽象類和接口的支持。例如,當(dāng)對象需要對象的能力時,可以有選擇地把對象的構(gòu)造器的原型指向?qū)ο螅瑥亩_(dá)到繼承的效果。本節(jié)內(nèi)容為設(shè)計模式與開發(fā)實踐第一章筆記。

動態(tài)類型語言

編程語言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語言與動態(tài)類型語言。

靜態(tài)類型語言在編譯時已確定變量類型,
動態(tài)類型語言的變量類型要到程序運行時,待變量被賦值后,才具有某種類型。

而JavaScript是一門典型的動態(tài)類型語言。

動態(tài)類型語言對變量類型的寬容使得編程變得很靈活。由于不用進(jìn)行類型檢測,我們可以調(diào)用任何對象的任意方法,而無需去考慮它原本是否被設(shè)計為擁有該方法。而這是建立在鴨子類型的概念上。

鴨子類型

鴨子類型通俗的說法是:

如果它走起路來像鴨子,叫起來也是鴨子,那么它就是鴨子。

鴨子類型指導(dǎo)我們只關(guān)注對象的行為,而不關(guān)注對象本身。

在動態(tài)類型語言的面向?qū)ο笤O(shè)計中,利用鴨子類型的思想,我們不必借助超類型的幫助,就能輕松地在動態(tài)類型語言中實現(xiàn)一個原則:“面向接口編程,而不是面向?qū)崿F(xiàn)編程”。例如:

一個對象若有push和pop方法,并且這些方法提供了正確的實現(xiàn),它就可以被當(dāng)作棧來使用;

一個對象若有l(wèi)ength屬性,且可以依照下標(biāo)來存取屬性,這個對象就可以被當(dāng)作數(shù)組來使用。

多態(tài) 多態(tài)的含義

同一操作作用于不同的對象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。

對象的多態(tài)性

我們說的多態(tài)性,其實就是對象的多態(tài)性,那么,對象的多態(tài)性是怎樣的?如何讓對象表現(xiàn)出多態(tài)性?

對象多態(tài)性的一個簡單的例子:

// 讓動物發(fā)聲
var makeSound = function(animal){
    animal.sound();
}
// 鴨子的叫聲
var Duck = function(){};
Duck.prototype.sound = function(){
    console.log("嘎嘎嘎");
};
// 小雞的叫聲
var Chicken = function(){};
Chicken.prototype.sound = function(){
    console.log("咯咯咯");
}

// 讓鴨子發(fā)聲
makeSound(new Duck());
// 讓小雞發(fā)聲
makeSound(new Chicken()); 

// 如果像讓小狗發(fā)聲,只需要簡單地追加類似的代碼
var Dog = function(){};
Dog.prototype.sound = function(){
    console.log("汪汪汪");
}
makeSound(new Dog());
類型檢查

靜態(tài)類型語言(例如Java)在編譯時會進(jìn)行類型匹配檢查,這種檢查在帶來安全性的同時,讓代碼顯得僵硬。因此,靜態(tài)類型語言通常被設(shè)計為可以向上轉(zhuǎn)型

當(dāng)給一個類變量賦值時,這個變量的類型既可以使用這個類本身,也可以使用這個類的超類。

就像我們在描述“一只麻雀在飛”,“一只喜鵲在飛”時,如果想忽略他們的具體類型,可以說成“一只鳥在飛”,這時“鳥”就是“麻雀”和“喜鵲”的超類。

而JavaScript是一門不必進(jìn)行類型檢查的動態(tài)類型語言。

多態(tài)的作用

多態(tài)是面向?qū)ο缶幊陶Z言中最重要的技術(shù)。

多態(tài)最根本的作用就是通過把過程化的條件分支語句轉(zhuǎn)化為對象的多態(tài)性,從而消除這些條件分支語句。有一個例子可以很好地詮釋:

在電影的拍攝現(xiàn)場,當(dāng)導(dǎo)演喊出“anciton”時,主角開始背臺詞,照明師負(fù)責(zé)打燈光,后面的群眾演員假裝中槍倒地,道具師往鏡頭里撒上雪花。在得到同一個消息時,每個對象都知道自己應(yīng)該做什么。如果不利用對象的多態(tài)性,而是用面向過程的方式來編寫這一段代碼,那么相當(dāng)于在電影開始拍攝后,導(dǎo)演每次都要走到每個人的面前,確認(rèn)他們的職業(yè)分工(類型),然后告訴他們要做什么。如果映射到程序中,那么程序中將充斥著條件分支語句。

將行為分布在各個對象中,并讓這些對象各自負(fù)責(zé)自己的行為,這正是面向?qū)ο笤O(shè)計的優(yōu)點。

多態(tài)與設(shè)計模式

從面向?qū)ο笤O(shè)計的角度出發(fā),通過對封裝、繼承、多態(tài)、組合等技術(shù)的反復(fù)使用,提煉出一些可重復(fù)使用的面向?qū)ο笤O(shè)計技巧,我們將其歸納為設(shè)計模式。而多態(tài)在其中是重中之重,絕大多部分設(shè)計模式的實現(xiàn)都離不開多態(tài)性的思想。例如:

命令模式

組合模式

策略模式

...

Javascript將函數(shù)作為一等對象,所以函數(shù)本身也是對象,函數(shù)用來封裝行為并且能夠四處傳遞。當(dāng)我們對一些函數(shù)發(fā)出“調(diào)用”的消息時,這些函數(shù)會返回不同的執(zhí)行結(jié)果,這是多態(tài)性的一種體現(xiàn)。

封裝

封裝的目的是將信息隱藏。封裝包括:

封裝數(shù)據(jù)

封裝實現(xiàn)

封裝類型

封裝變化

封裝數(shù)據(jù)

在許多語言的對象系統(tǒng)中,封裝數(shù)據(jù)是由語法解析來實現(xiàn)的,這些語言可能提供了private、public、protected等關(guān)鍵字來提供不同的訪問權(quán)限。但JavaScript并沒有提供對這些關(guān)鍵字的支持,只能依賴變量的作用域來實現(xiàn)封裝特性,而且只能模擬出public和private這兩種封裝性。

一般我們通過函數(shù)來創(chuàng)建作用域:

var myObject = (function(){
    var __name = "sven";    //私有(private)變量
    return {
        getName:function(){        //公開(public)方法
            return __name;
        }
    }
})();

console.log(myObject.getName());    //輸出:sven
console.log(myObject.__name);        //輸出:undefined
封裝實現(xiàn)

從封裝實現(xiàn)細(xì)節(jié)來講,封裝使得對象內(nèi)部的變化對其他對象而言是透明的(即不可見)。對象對它自己的行為負(fù)責(zé)。其他對象或者用戶都不關(guān)心它的內(nèi)部實現(xiàn)。對象使得對象之間的耦合變得松散,對象之間只通過暴露的API接口來通信。

封裝實現(xiàn)細(xì)節(jié)的例子非常多,例如迭代器。迭代器的作用是在不暴露一個聚合對象的內(nèi)部表示的前提下,提供一種方式來順序訪問這個聚合對象。如一個each函數(shù),它的作用就是遍歷一個聚合對象,使用這個each函數(shù)的人不用關(guān)心它的內(nèi)部代碼是怎么實現(xiàn)的,只要它提供的功能正確便可以了。

封裝類型

封裝類型是靜態(tài)類型語言的一種重要封裝方式。封裝類型是通過抽象類和接口來進(jìn)行的。

在JavaScript中,并沒有對抽象類和接口的支持。JavaScript本身也是一門類型模糊的語言。在封裝類型方面,JavaScript沒有能力,也沒有必要做得更多。

封裝變化

從設(shè)計模式的角度出發(fā),封裝在更重要的層面體現(xiàn)為封裝變化。

通過封裝變化的方式,把系統(tǒng)中穩(wěn)定不變的部分和容易變化的部分隔離開來,在系統(tǒng)的演變過程中,我們只需要替換掉那些容易變化的部分,如果這些部分是已經(jīng)封裝好的,替換起來也想對容易。這可以最大程度地保證程序的穩(wěn)定性和可擴展性。

原型模式 原型模式

原型模式是用于創(chuàng)建對象的一種模式。

原型模式不用關(guān)心對象的具體類型,只需找到一個對象,然后通過克隆來創(chuàng)造一個一模一樣的對象。

原型模式的實現(xiàn)關(guān)鍵是語言本身是否提供了clone方法,ECMAScript5提供了Object.create方法,可以用來克隆對象。

原型模式的真正目的不在于需要得到一模一樣的對象,而是提供了一種便捷的方式去創(chuàng)建某個類型的對象,克隆只是創(chuàng)建這個對象的過程和手段。

在JavaScript這種類型模糊的語言中,創(chuàng)建對象非常容易,也不存在類型耦合的問題。從設(shè)計模式的角度來看,原型模式的意義并不算大。但JavaScript本身是一門基于原型的面向?qū)ο笳Z言,它的對象系統(tǒng)就是使用原型模式來搭建的,在這里稱為原型編程范型也許更合適。

原型編程范型

原型編程中有一個重要特性,即當(dāng)對象無法響應(yīng)某個請求時,會把該請求委托給它自己的原型。

而原型編程范型至少包括以下基本原則:

所有的數(shù)據(jù)都是對象

要得到一個對象,不是通過實例化類,而是找到一個對象作為原型并克隆它

對象會記住它的原型

如果對象無法響應(yīng)某個請求,它會把這個請求委托給它自己的原型

JavaScript中的原型繼承

JavaScript在原型編程范型的規(guī)則的基礎(chǔ)上來構(gòu)建它的對象系統(tǒng)。

所有的數(shù)據(jù)都是對象

JavaScript在設(shè)計的時候,模仿Java引入了兩套類型機制:基本類型和對象類型。

按照J(rèn)avaScript設(shè)計者的本意,除了undefined之外,一切都應(yīng)是對象。為了實現(xiàn)這一目標(biāo),number、boolean等幾種基本類型數(shù)據(jù)可以通過“包裝類”的方式變成對象類型數(shù)據(jù)。

JavaScript絕大部分?jǐn)?shù)據(jù)都是對象。事實上,JavaScript中的根對象是Object.prototype對象。Object.prototype對象是一個空對象。JavaScript的每個對象,都是從Object.prototype對象克隆而來。

要得到一個對象,不是通過實例化類,而是找到一個對象作為原型并克隆它

JavaScript通過顯式地調(diào)用 var obj1 = new Object() , 或者 var obj2 = {} 。此時,引擎內(nèi)部會從Object.prototype上面克隆一個對象出來。

這里用了new運算符從構(gòu)造器中得到了一個對象。在JavaScript里,函數(shù)既可以作為普通的函數(shù)被調(diào)用,也可以作為構(gòu)造器被調(diào)用。用new運算符來創(chuàng)建對象的過程,實際上也只是先克隆Object.prototype對象,再進(jìn)行一些其他額外操作的過程。

對象會記住它的原型

就JavaScript的真正實現(xiàn)來說,其實并不能說對象有原型,而只能說對象的構(gòu)造器有原型。“對象把請求委托給它自己的原型”就是對象把請求委托給它的構(gòu)造器的原型。

JavaScript給對象提供了一個名為__proto__的隱藏屬性,某個對象的__proto__屬性默認(rèn)會指向它的構(gòu)造器的原型對象,即{Constructor}.prototype。在一些瀏覽器中,__proto__被公開出來。

如果對象無法響應(yīng)某個請求,它會把這個請求委托給它自己的原型

這條規(guī)則是原型繼承的精髓所在。當(dāng)一個對象無法響應(yīng)某個請求時,它會順著原型鏈把請求傳遞下去,直到遇到一個可以處理請求的對象為止。

雖然JavaScript的對象最初都是由Object.prototype對象克隆而來,但對象構(gòu)造器的原型并不僅限于Object.prototype上,而是可以動態(tài)地指向其他對象。例如,當(dāng)對象A需要對象B的能力時,可以有選擇地把對象A的構(gòu)造器的原型指向?qū)ο驜,從而達(dá)到繼承的效果。

PS:本節(jié)內(nèi)容為《JavaScript設(shè)計模式與開發(fā)實踐》第一章 筆記。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86114.html

相關(guān)文章

  • JavaScript設(shè)計模式開發(fā)實踐》 —— <閱讀小札·一>

    摘要:閱讀小札一閱讀前自大學(xué)課上,就開始接觸設(shè)計模式,但對設(shè)計模式卻鮮有研究與實踐。第二部分是核心部分,由淺到深講解個設(shè)計模式。設(shè)計模式遵循的原則所有設(shè)計模式罪訓(xùn)的一條原則就是找出程序中變化的地方,并將變化封裝起來。 閱讀小札 · 閱讀前 自大學(xué)Java課上,就開始接觸設(shè)計模式,但對設(shè)計模式卻鮮有研究與實踐。最近向公司反映和游說技術(shù)提升,得以獲得公司提供購書機會,借此認(rèn)真學(xué)習(xí)前端學(xué)習(xí)之路的...

    Yangder 評論0 收藏0
  • javascript設(shè)計模式開發(fā)實踐全書深度解析(一)之前言

    摘要:相信很多人都看過設(shè)計模式與開發(fā)實踐這本書,每個人都有自己的體會感受,作為前端年開發(fā)經(jīng)驗的程序猿,用我自認(rèn)為還可以的實踐經(jīng)驗來與大家談?wù)勥@本書。這章是前言,后面陸續(xù)會講解每個設(shè)計模式。 相信很多人都看過《javascript設(shè)計模式與開發(fā)實踐》這本書,每個人都有自己的體會感受,作為前端3年開發(fā)經(jīng)驗的程序猿,用我自認(rèn)為還可以的實踐經(jīng)驗來與大家談?wù)勥@本書。這章是前言,后面陸續(xù)會講解每個設(shè)計模...

    timger 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<