JavaScript精粹讀書筆記(1,2)

來源:互聯網
上載者:User

From:http://student.csdn.net/space.php?uid=45106&do=blog&view=me

第1章      精華JavaScript的特性中有一部分特性帶來的麻煩遠遠超出它們的價值。其中,一些特性是因為規範很不完善,從而可能導致可移植性的問題;一些特性會導致產生難以理解和修改的代碼;一些特性促使My Code風格過於複雜且易於出錯;還有一些特性就是設計錯誤。有時候語言的設計者也會犯錯。大多數程式設計語言都有精華部分和雞肋部分。我發現如果只使用精華部分而避免使用雞肋的部分,我可以成為一個更好的程式員。畢竟,用糟糕的組件怎麼可能構建出好東西呢?標準委員會想要移除一門語言中的缺陷部分,這幾乎是不可能的,因為這樣做會損害所有依賴於那些雞肋部分的糟糕程式。除了在已存在的一大堆缺陷上堆積更多的特性,他們通常無能為力。並且新舊特性並不總是能和諧共處,可能從而產生出更多的雞肋部分。但是,你有權力定義你自己的子集。你完全可以基於精華部分去編寫更好的程式。JavaScript中雞肋部分的比重超出了預料。在短到令人吃驚的時間裡,它從不存在發展到全球採用。它從來沒有在實驗室裡被試用和打磨。當它還非常粗糙時,它就被直接整合到網景的Navigator 2瀏覽器中。隨著JavaTM的小應用程式(Java applets)的失敗,JavaScript變成了預設的“網頁語言”。作為一門程式設計語言,JavaScript的流行幾乎完全不受它的品質的影響。好在JavaScript有一些非常精華的部分。JavaScript最本質的部分被深深地隱藏著,以至於多年來對它的主流觀點是:JavaScript就是一個醜陋的、沒用的玩具。本書的目的就是要揭示JavaScript中的精華,讓大家知道它是一門傑出的動態程式設計語言。或許只學習精華部分的最大好處就是你可以不用考慮雞肋的部分。忘掉不好的模式是非常困難的。這是一個非常痛苦的工作,我們中的大多數人都會很不願意麵對。有時候,制定語言的子集是為了讓學生更好的學習。但在這裡,我制定的JavaScript子集是為了主專業人員更好的工作。1.1     為什麼要使用JavaScriptJavaScript是一門重要的語言,因為它是web瀏覽器的語言。它與瀏覽器的結合使它成為世界上最流行的程式設計語言之一。同時,它也是世界上最被輕視的程式設計語言之一。瀏覽器的API和文件物件模型(DOM)相當糟糕,導致JavaScript遭到不公平的指責。JavaScript是最被輕視的語言,因為它不是所謂的主流語言。如果你擅長某些主流語言,但卻在一個只支援JavaScript的環境中編程,那麼被迫使用JavaScript確是相當令人厭煩的。大多數人覺得沒必要去先學好JavaScript,但結果他們會驚訝地發現,JavaScript跟他們寧願使用的主流語言有很大不同,而且這些不同至為關鍵。JavaScript令人驚異的事情是,在對這門語言沒有太多瞭解,甚至對編程都沒有太多瞭解的情況下,你也能用它來完成工作。它是一門擁有極強表達能力的語言。當你知道要做什麼時,它甚至能表現得更好。編程是很困難的事情。絕不應該在對此一無所知時便開始你的工作。1.2     分析JavaScriptJavaScript建立在一些非常好的想法和少數非常壞的想法之上。那些非常好的想法包括函數、弱類型、動態對象和一個富有表現力的字面量標記法。那些壞的想法包括基於全域變數的編程模型。JavaScript的函數是(主要)基於詞法範圍(lexical scoping)的頂級對象。JavaScript是第一個成為主流的lambda語言。實際上,相對Java而言,JavaScript與Lisp和Scheme有更多的共同點。它是披著C外衣的Lisp。這使得JavaScript成為一個非常強大的語言。現今大部分程式設計語言中都流行要求強型別。其原理在於強型別允許編譯器在編譯時間檢測錯誤。我們能越早檢測和修複錯誤,付出的代價就越小。JavaScript是一門弱類型的語言,所以JavaScript編譯器不能檢測出類型錯誤。另一方面,弱類型其實是自由的。我們無須建立複雜的次,我永遠不用做強制類型轉換,也不用疲於應付類型系統以得到想要的行為。JavaScript有非常強大的對象字面量標記法。通過列出對象的組成部分,它們就能簡單地被建立出來。這種標記法產生了流行的資料交換格式——JSON。原型繼承是JavaScript中一個有爭議的特性。JavaScript有一個無類別(class-free)的對象系統,在這個系統中,對象直接從其他對象繼承屬性。這真的很強大,但是對那些被訓練使用類去建立對象的程式員們來說,原型繼承是一個陌生的概念。如果你嘗試對JavaScript直接應用基於類的設計模式,你將會遭受挫折。但是,如果你學習使用JavaScript的原型本質,那麼你的努力將會有所回報。JavaScript在關鍵思想的選擇上飽受非議。雖然在大多數情況下,這些選擇是合適的。但是有一個選擇相當糟糕:JavaScript依賴於全域變數來進行串連。所有編譯單元的所有頂級變數被撮合到一個被稱為全域對象的公用命名空間中。這是一件糟糕的事情,因為全域變數是魔鬼,並且在JavaScript中它們是基礎性的。在少數情況下,我們不能忽略雞肋的部分。另外還有一些不可避免的糟粕,當涉及這些部分時,我們會將它們指出來。如果你想學習那些雞肋的部分及如何拙劣地使用它們,請參閱任何其他的JavaScript書籍。JavaScript是一門有許多差異的語言。它包含很多錯誤和尖銳的邊角(sharp edges),所以你可能會疑惑:“為什麼我要使用JavaScript?”有兩個答案。第一個是你沒有選擇。Web已變成一個重要的應用開發平台,而JavaScript是唯一一門所有瀏覽器都可以識別的語言。很不幸,Java在瀏覽器環境中失敗了。JavaScript的蓬勃發展,恰恰說明了JavaScript確有其過人之處。另一個答案是,儘管JavaScript有缺陷,但是它真的很優秀。它既輕量又富有表現力。並且一旦你熟練掌握了它,就會發現函數式編程是一件很有趣的事。但是為了更好地使用這門語言,你必須知道它的局限。我將會無情地揭示它們。不要因此而氣餒。這門語言的精華部分足以彌補它雞肋的不足。1.3     一個簡單的實驗場如果你有一個Web瀏覽器和任意一個文字編輯器,那麼你就有了運行JavaScript程式所需要的一切。首先,請建立一個HTML檔案,可以命名為program.html: <html>        <body>               <pre>                             <script src="program.js"></script>               </pre>        </body> </html>接下來,在同一個檔案夾內,建立一個指令檔,可以命名為program.js: document.writeln('Hello, world!');下一步,用你的瀏覽器找開你的HTML檔案去查看結果。本書貫徹始終都會用到一個method方法去定義新方法。下面是它的定義: Function.prototype.method=function(name,func){        this.prototype[name]=func;        return this; }我會在第4章解釋它。第2章      文法本章介紹JavaScript的精華部分的文法,並簡要地概述其語言結構。2.1     空白空白可能表現為格式化字元或注釋的形式。空白通常沒有意義,但是偶爾須要用它來分隔字元序列,否則它們就會被合并成一個單一的符號。例如,對如下代碼來說: var that = this;var和that之間的空格是不能被移除的,但是其他的空格都可以被移除。JavaScript提供兩種注釋形式,一種是用/* */包圍的塊注釋,另一種是以//為開頭的行注釋。注釋應該被充分地用來提高程式的可讀性。必須注意的是,注釋一定要精確地描述代碼。沒有用的注釋比沒有注釋更糟糕。用/* */包圍的塊注釋形式來自於一門叫PL/I( 默然說話:Programming Language One的簡寫。當中的“I”其實是羅馬數位“一”,它是一種IBM公司在19世紀50年代發明的第三代進階程式設計語言)的語言。在JavaScript中,*/可能出現在Regex字面上,所以塊注釋對於被注釋的代碼塊來說是不安全的。例如: /*        var rm_a = /a*/.match(s); */導致了一個語法錯誤。所以,我建議避免使用/* */注釋,而用//注釋代替它。2.2     標識符標識符由一個字母開頭,其後可選擇性地加上一個或多個字母數字或底線。標識符不能使用下面這些保留字:abstractboolean break bytecase catch char class const continuedebugger default delete do doubleelse enum export extendsfalse final finally float for functiongotoif implements import in instanceof int interfacelongnative new nullpackage private protected publicreturnshort static super switch synchronizedthis throw throws transient true try typeofvar volatile voidwhile with在這個列表中的大部分保留字尚未用在這門語言中。這個列表不包括一些本應該被保留而沒有保留的字,諸如undefined、NaN和Infinity。JavaScript不允許使用保留字來命名變數或參數。更糟糕的是,JavaScript不允許在對象字面量中,或者在一個屬性存取運算式的點號之後,使用保留字作為對象的屬性名稱。標識符被用於語句、變數、參數、屬性名稱、運算子和標記。2.3     數字JavaScript只有一個單一的數字類型。它在內部被表示為64位的浮點數,和Java的double一樣。在JavaScript中,1和1.0是相同的值。如果一個數字字面量有指數部分,那麼這個字面量的值是由e之前的部分乘以10的e之後部分的次方計算出來的。所以100和1e2是相同的數字。負數可以用首碼運算子-來構成。值NaN是一個數值,它表示一個不能產生正常結果的運算結果。NaN不等於任何值,包括它自己。你可以用函數isNaN(number)檢測NaN。值Infinity表示所有大於1.79769313486231570e+308的值。數字擁有方法(參見第8章)。JavaScript有一個對象Math,它包含一套作用於數位方法。例如,可以用Math.floor(number)方法將一個數字轉換成一個整數。2.4     字串字串字面量可以被包圍在單引號或雙引號中,它可能包含0個或多個字元。\是逸出字元。JavaScript在被建立的時候,Unicode是一個16位的字元集,所以JavaScript中的所有字元都是16位的。JavaScript沒有字元類型。要表示一個字元,只須建立僅包含一個字元的字串即可。逸出字元允許把那些正常情況下不被允許的字元插入到字串中,比如反斜線、引號和控制字元。\u約定允許指定用數字表示的字元碼位。“A”===”\u0041”字串有一個ength屬性。例如,”seven”.length是5。字串是不可變的。一旦字串被建立,就永遠無法改變它。但通過+運算子去串連其他的字串從而得到一個新字串是很容易的。兩個包含著完全相同的字元且字元順序也相同的字串被認為是相同的字串。所以: ‘c’+’a’+’t’ === ‘cat’是true。字串有一些方法(參見第8章)。2.5     語句一個編譯單元包含一組可執行檔語句。在web瀏覽器中,每個<script>標籤都提供一個被編譯且立即執行的編譯單元。因為缺少連結器,JavaScript把它們一起拋入一個公用的全域命名空間中。附錄A有更多關於全域變數的內容。當var語句被用在函數的內部時,它定義了這個函數的私人變數。switch、while、for和do語句允許有一個可選的前置標籤(label),它配合break語句來使用。語句往往按照從上到下的順序被執行。JavaScript可以通過條件陳述式(if和switch)、迴圈語句(while、for和do)、強制跳躍陳述式(break、return和throw)和函數調用來改變這個執行序列。代碼塊是包在一對花括弧中的一組語句。不像許多其他的語言,JavaScript中的代碼塊不會建立一個新的範圍,因此變數應該被定義在函數的頂端,而不是在代碼塊中。if語句根據運算式的值改變程式的控制流程程。如果運算式的值為真,那麼執行then代碼塊,否則,執行可選的else分支。下面列出的值被當作假:fasenullundefined數字0數字NaN其他所有的值都被當作真,包括true,字串”false”,以及所有的對象。switch語句執行一個多路分支。它把其運算式的值和所有指定的case條件進行匹配。其運算式可能產生一個數字或字串。當找到一個精確的匹配時,執行匹配的case從句中的語句。如果沒有找到任何匹配,則執行可選的default語句。一個case從句包含一個或多個case運算式。case運算式不一定必須是常量。為了防止繼續執行下一個case,case語句後應該跟隨一上強制跳躍陳述式。你可以用break語句去退出一個switch語句。while語句執行一個簡單的迴圈。如果運算式值為假,那麼迴圈將終止。而當運算式值為真時,代碼塊將被執行。for語句是一個結構更複雜的迴圈語句。它有兩種形式。常見的形式由三個可選從句控制:初始化從句(initialization)、條件從句(condition)和增量從句(increment)。首先,;初始化從句被執行,它的作用通常是初始化迴圈變數。接著計算條件從句的值。典型的情況是它根據一個完成條件檢測迴圈變數。如果條件從句被省略掉,則假定返回的條件是真。如果條件從句的值為假,那麼迴圈將終止。否則,執行代碼塊,然後執行增量從句,接著迴圈會重複執行條件從句。另一種形式(被稱為for in語句)會枚舉一個對象的所有屬性名稱(或鍵名)。在每次迴圈中,對象的另一個屬性名稱字串被賦值給for和in之間的變數。通常你須通過檢測object.hasOwnProperty(variable)來確定這個屬性名稱就是該對象的成員,還是從其原型鏈裡找到的。 for(myvar in obj){        if(obj.hasOwnProperty(myvar)){               …        } }do語句就像while語句,唯一的區別是它在代碼塊執行之後而不是之前檢測運算式的值。這就意味著代碼塊將總是要執行至少一次。try語句執行一個代碼塊,並捕獲該代碼塊拋出的任何異常。catch從句定義了一個新的變數,它將接收該異常對象。throw語句拋出一個異常。如果throw語句在一個try代碼塊中,那麼控制權會跳到catch從句中。如果throw語句在函數中,則該函數調用被放棄,且控制權會跳到調用該函數的try語句的catch從句中。throw語句中的運算式通常是一個對象字面量,它包含一個name屬性和一個message屬性。異常捕獲器可以使用這些資訊去決定該做什麼。return語句會使一人函數提前返回。它也可以指定要被返回的值。如果沒有指定返回運算式,那麼其傳回值是undefined。JavaScript不允許在return關鍵字和運算式之間換行。break語句會使程式退出一個迴圈語句或switch語句。它可以指定一個可選的標籤,那將會使程式退出帶該標籤的語句。JavaScript不允許在break關鍵字和標籤之間換行。一個expression語句可以給一個或多個變數或成員賦值,或者調用一個方法,或者從對象中刪除一個屬性。運算子=被用於賦值。不要把它和恒等運算子===混淆。運算子+=可以用於加法運算或連接字串。2.6     運算式三元運算子?有三個運算數。如果第一個運算數值為真,它產生第二個運算數的值。但是,如果第一個運算數為假,它會產生第三個運算數的值。表2-1:運算子優先順序
.[]() 屬性存取及函數調用
delete new typeof +-! 一元運算子
*/% 乘法、除法、模數
+- 加法/串連、減法
>= <= > < 不等式運算子
=== !== 等式運算子
&& 邏輯與
|| 邏輯或
?: 三元
typeo運算子產生的值有’number’、’string’、’boolean’、’undefined’、’function’、’object’。如果運算數是一個數組或null,那麼結果是’object’,這是不對的。第6章和附錄A將會有更多關於typeof的內容。/運算子可能會產生一個非整數結果,即使兩個運算數都是整數。函數調用引發函數的執行。函數調用運算子是跟隨在函數名後面的一對圓括弧。圓括弧中可能包含將會傳遞給這個函數的參數。第4章將會有更多關於函數的內容。一個屬性存取運算式用於指定一個對象或數組的屬性或元素。下一章我將詳細描述它。2.7     字面量對象字面量是一種方便指定新對象的標記法。屬性名稱可以是標識符或字串。這些名字被當作字面量名而不是變數名來對待,所以對象的屬性名稱在編譯時間才能知道。屬性的值就是運算式。下一章將會有更多關於對象字面量的資訊。數組字面量是一個方便指定新數組的標記法。第6章將會有更多關於數組字面量的內容。第7章將會有更多關於Regex的內容。

函數字面量定義了函數值。它可以有一個可選的名字,用於遞迴地調用自己。它可以指定一個參數列表,這些參數將作為變數由調用時傳遞的實際參數(arguments)初始化。函數的主體包括變數定義和語句。第4章將會有更多關於函數的內容。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.