亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時(shí)間:2010年02月07日 11:29:09   作者:  
JavaScript的特性中有一部分特性帶來的麻煩遠(yuǎn)遠(yuǎn)超出它們的價(jià)值。
第1章 精華
JavaScript的特性中有一部分特性帶來的麻煩遠(yuǎn)遠(yuǎn)超出它們的價(jià)值。其中,一些特性是因?yàn)橐?guī)范很不完善,從而可能導(dǎo)致可移植性的問題;一些特性會(huì)導(dǎo)致生成難以理解和修改的代碼;一些特性促使我的代碼風(fēng)格過于復(fù)雜且易于出錯(cuò);還有一些特性就是設(shè)計(jì)錯(cuò)誤。有時(shí)候語言的設(shè)計(jì)者也會(huì)犯錯(cuò)。
大多數(shù)編程語言都有精華部分和雞肋部分。我發(fā)現(xiàn)如果只使用精華部分而避免使用雞肋的部分,我可以成為一個(gè)更好的程序員。畢竟,用糟糕的部件怎么可能構(gòu)建出好東西呢?
標(biāo)準(zhǔn)委員會(huì)想要移除一門語言中的缺陷部分,這幾乎是不可能的,因?yàn)檫@樣做會(huì)損害所有依賴于那些雞肋部分的糟糕程序。除了在已存在的一大堆缺陷上堆積更多的特性,他們通常無能為力。并且新舊特性并不總是能和諧共處,可能從而產(chǎn)生出更多的雞肋部分。
但是,你有權(quán)力定義你自己的子集。你完全可以基于精華部分去編寫更好的程序。JavaScript中雞肋部分的比重超出了預(yù)料。在短到令人吃驚的時(shí)間里,它從不存在發(fā)展到全球采用。它從來沒有在實(shí)驗(yàn)室里被試用和打磨。當(dāng)它還非常粗糙時(shí),它就被直接集成到網(wǎng)景的Navigator 2瀏覽器中。隨著JavaTM的小應(yīng)用程序(Java applets)的失敗,JavaScript變成了默認(rèn)的“網(wǎng)頁語言”。作為一門編程語言,JavaScript的流行幾乎完全不受它的質(zhì)量的影響。
好在JavaScript有一些非常精華的部分。JavaScript最本質(zhì)的部分被深深地隱藏著,以至于多年來對它的主流觀點(diǎn)是:JavaScript就是一個(gè)丑陋的、沒用的玩具。本書的目的就是要揭示JavaScript中的精華,讓大家知道它是一門杰出的動(dòng)態(tài)編程語言。
或許只學(xué)習(xí)精華部分的最大好處就是你可以不用考慮雞肋的部分。忘掉不好的模式是非常困難的。這是一個(gè)非常痛苦的工作,我們中的大多數(shù)人都會(huì)很不愿意面對。有時(shí)候,制定語言的子集是為了讓學(xué)生更好的學(xué)習(xí)。但在這里,我制定的JavaScript子集是為了主專業(yè)人員更好的工作。
1.1 為什么要使用JavaScript
JavaScript是一門重要的語言,因?yàn)樗莣eb瀏覽器的語言。它與瀏覽器的結(jié)合使它成為世界上最流行的編程語言之一。同時(shí),它也是世界上最被輕視的編程語言之一。瀏覽器的API和文檔對象模型(DOM)相當(dāng)糟糕,導(dǎo)致JavaScript遭到不公平的指責(zé)。
JavaScript是最被輕視的語言,因?yàn)樗皇撬^的主流語言。如果你擅長某些主流語言,但卻在一個(gè)只支持JavaScript的環(huán)境中編程,那么被迫使用JavaScript確是相當(dāng)令人厭煩的。大多數(shù)人覺得沒必要去先學(xué)好JavaScript,但結(jié)果他們會(huì)驚訝地發(fā)現(xiàn),JavaScript跟他們寧愿使用的主流語言有很大不同,而且這些不同至為關(guān)鍵。
JavaScript令人驚異的事情是,在對這門語言沒有太多了解,甚至對編程都沒有太多了解的情況下,你也能用它來完成工作。它是一門擁有極強(qiáng)表達(dá)能力的語言。當(dāng)你知道要做什么時(shí),它甚至能表現(xiàn)得更好。編程是很困難的事情。絕不應(yīng)該在對此一無所知時(shí)便開始你的工作。
1.2 分析JavaScript
JavaScript建立在一些非常好的想法和少數(shù)非常壞的想法之上。
那些非常好的想法包括函數(shù)、弱類型、動(dòng)態(tài)對象和一個(gè)富有表現(xiàn)力的字面量表示法。那些壞的想法包括基于全局變量的編程模型。
JavaScript的函數(shù)是(主要)基于詞法作用域(lexical scoping)的頂級對象。JavaScript是第一個(gè)成為主流的lambda語言。實(shí)際上,相對Java而言,JavaScript與Lisp和Scheme有更多的共同點(diǎn)。它是披著C外衣的Lisp。這使得JavaScript成為一個(gè)非常強(qiáng)大的語言。
現(xiàn)今大部分編程語言中都流行要求強(qiáng)類型。其原理在于強(qiáng)類型允許編譯器在編譯時(shí)檢測錯(cuò)誤。我們能越早檢測和修復(fù)錯(cuò)誤,付出的代價(jià)就越小。JavaScript是一門弱類型的語言,所以JavaScript編譯器不能檢測出類型錯(cuò)誤。另一方面,弱類型其實(shí)是自由的。我們無須建立復(fù)雜的次,我永遠(yuǎn)不用做強(qiáng)制類型轉(zhuǎn)換,也不用疲于應(yīng)付類型系統(tǒng)以得到想要的行為。
JavaScript有非常強(qiáng)大的對象字面量表示法。通過列出對象的組成部分,它們就能簡單地被創(chuàng)建出來。這種表示法產(chǎn)生了流行的數(shù)據(jù)交換格式——JSON。
原型繼承是JavaScript中一個(gè)有爭議的特性。JavaScript有一個(gè)無類別(class-free)的對象系統(tǒng),在這個(gè)系統(tǒng)中,對象直接從其他對象繼承屬性。這真的很強(qiáng)大,但是對那些被訓(xùn)練使用類去創(chuàng)建對象的程序員們來說,原型繼承是一個(gè)陌生的概念。如果你嘗試對JavaScript直接應(yīng)用基于類的設(shè)計(jì)模式,你將會(huì)遭受挫折。但是,如果你學(xué)習(xí)使用JavaScript的原型本質(zhì),那么你的努力將會(huì)有所回報(bào)。
JavaScript在關(guān)鍵思想的選擇上飽受非議。雖然在大多數(shù)情況下,這些選擇是合適的。但是有一個(gè)選擇相當(dāng)糟糕:JavaScript依賴于全局變量來進(jìn)行連接。所有編譯單元的所有頂級變量被撮合到一個(gè)被稱為全局對象的公共命名空間中。這是一件糟糕的事情,因?yàn)槿肿兞渴悄Ч恚⑶以贘avaScript中它們是基礎(chǔ)性的。
在少數(shù)情況下,我們不能忽略雞肋的部分。另外還有一些不可避免的糟粕,當(dāng)涉及這些部分時(shí),我們會(huì)將它們指出來。如果你想學(xué)習(xí)那些雞肋的部分及如何拙劣地使用它們,請參閱任何其他的JavaScript書籍。
JavaScript是一門有許多差異的語言。它包含很多錯(cuò)誤和尖銳的邊角(sharp edges),所以你可能會(huì)疑惑:“為什么我要使用JavaScript?”有兩個(gè)答案。第一個(gè)是你沒有選擇。Web已變成一個(gè)重要的應(yīng)用開發(fā)平臺(tái),而JavaScript是唯一一門所有瀏覽器都可以識(shí)別的語言。很不幸,Java在瀏覽器環(huán)境中失敗了。JavaScript的蓬勃發(fā)展,恰恰說明了JavaScript確有其過人之處。
另一個(gè)答案是,盡管JavaScript有缺陷,但是它真的很優(yōu)秀。它既輕量又富有表現(xiàn)力。并且一旦你熟練掌握了它,就會(huì)發(fā)現(xiàn)函數(shù)式編程是一件很有趣的事。
但是為了更好地使用這門語言,你必須知道它的局限。我將會(huì)無情地揭示它們。不要因此而氣餒。這門語言的精華部分足以彌補(bǔ)它雞肋的不足。
1.3 一個(gè)簡單的試驗(yàn)場
如果你有一個(gè)Web瀏覽器和任意一個(gè)文本編輯器,那么你就有了運(yùn)行JavaScript程序所需要的一切。首先,請創(chuàng)建一個(gè)HTML文件,可以命名為program.html:
復(fù)制代碼 代碼如下:

<html>
<body>
<pre>
<script src="program.js"></script>
</pre>
</body>
</html>

接下來,在同一個(gè)文件夾內(nèi),創(chuàng)建一個(gè)腳本文件,可以命名為program.js:
document.writeln('Hello, world!');
下一步,用你的瀏覽器找開你的HTML文件去查看結(jié)果。本書貫徹始終都會(huì)用到一個(gè)method方法去定義新方法。下面是它的定義:
復(fù)制代碼 代碼如下:

Function.prototype.method=function(name,func){
this.prototype[name]=func;
return this;
}

我會(huì)在第4章解釋它。
第2章 語法
本章介紹JavaScript的精華部分的語法,并簡要地概述其語言結(jié)構(gòu)。
2.1 空白
空白可能表現(xiàn)為格式化字符或注釋的形式。空白通常沒有意義,但是偶爾須要用它來分隔字符序列,否則它們就會(huì)被合并成一個(gè)單一的符號(hào)。例如,對如下代碼來說:
var that = this;
var和that之間的空格是不能被移除的,但是其他的空格都可以被移除。
JavaScript提供兩種注釋形式,一種是用/* */包圍的塊注釋,另一種是以//為開頭的行注釋。注釋應(yīng)該被充分地用來提高程序的可讀性。必須注意的是,注釋一定要精確地描述代碼。沒有用的注釋比沒有注釋更糟糕。
用/* */包圍的塊注釋形式來自于一門叫PL/I(默然說話:Programming Language One的簡寫。當(dāng)中的“I”其實(shí)是羅馬數(shù)字的“一”,它是一種IBM公司在19世紀(jì)50年代發(fā)明的第三代高級編程語言)的語言。在JavaScript中,*/可能出現(xiàn)在正則表達(dá)式字面上,所以塊注釋對于被注釋的代碼塊來說是不安全的。例如:
/*
var rm_a = /a*/.match(s);
*/
導(dǎo)致了一個(gè)語法錯(cuò)誤。所以,我建議避免使用/* */注釋,而用//注釋代替它。
2.2 標(biāo)識(shí)符
標(biāo)識(shí)符由一個(gè)字母開頭,其后可選擇性地加上一個(gè)或多個(gè)字母數(shù)字或下劃線。標(biāo)識(shí)符不能使用下面這些保留字:
abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with
在這個(gè)列表中的大部分保留字尚未用在這門語言中。這個(gè)列表不包括一些本應(yīng)該被保留而沒有保留的字,諸如undefined、NaN和Infinity。JavaScript不允許使用保留字來命名變量或參數(shù)。更糟糕的是,JavaScript不允許在對象字面量中,或者在一個(gè)屬性存取表達(dá)式的點(diǎn)號(hào)之后,使用保留字作為對象的屬性名。
標(biāo)識(shí)符被用于語句、變量、參數(shù)、屬性名、運(yùn)算符和標(biāo)記。
2.3 數(shù)字
JavaScript只有一個(gè)單一的數(shù)字類型。它在內(nèi)部被表示為64位的浮點(diǎn)數(shù),和Java的double一樣。在JavaScript中,1和1.0是相同的值。
如果一個(gè)數(shù)字字面量有指數(shù)部分,那么這個(gè)字面量的值是由e之前的部分乘以10的e之后部分的次方計(jì)算出來的。所以100和1e2是相同的數(shù)字。
負(fù)數(shù)可以用前綴運(yùn)算符-來構(gòu)成。
值NaN是一個(gè)數(shù)值,它表示一個(gè)不能產(chǎn)生正常結(jié)果的運(yùn)算結(jié)果。NaN不等于任何值,包括它自己。你可以用函數(shù)isNaN(number)檢測NaN。
值Infinity表示所有大于1.79769313486231570e+308的值。
數(shù)字擁有方法(參見第8章)。JavaScript有一個(gè)對象Math,它包含一套作用于數(shù)字的方法。例如,可以用Math.floor(number)方法將一個(gè)數(shù)字轉(zhuǎn)換成一個(gè)整數(shù)。
2.4 字符串
字符串字面量可以被包圍在單引號(hào)或雙引號(hào)中,它可能包含0個(gè)或多個(gè)字符。\是轉(zhuǎn)義字符。JavaScript在被創(chuàng)建的時(shí)候,Unicode是一個(gè)16位的字符集,所以JavaScript中的所有字符都是16位的。
JavaScript沒有字符類型。要表示一個(gè)字符,只須創(chuàng)建僅包含一個(gè)字符的字符串即可。
轉(zhuǎn)義字符允許把那些正常情況下不被允許的字符插入到字符串中,比如反斜線、引號(hào)和控制字符。\u約定允許指定用數(shù)字表示的字符碼位。
“A”===”\u0041”
字符串有一個(gè)ength屬性。例如,”seven”.length是5。
字符串是不可變的。一旦字符串被創(chuàng)建,就永遠(yuǎn)無法改變它。但通過+運(yùn)算符去連接其他的字符串從而得到一個(gè)新字符串是很容易的。兩個(gè)包含著完全相同的字符且字符順序也相同的字符串被認(rèn)為是相同的字符串。所以:
‘c'+'a'+'t' === ‘cat'
是true。
字符串有一些方法(參見第8章)。
2.5 語句
一個(gè)編譯單元包含一組可執(zhí)行的語句。在web瀏覽器中,每個(gè)<script>標(biāo)簽都提供一個(gè)被編譯且立即執(zhí)行的編譯單元。因?yàn)槿鄙冁溄悠?,JavaScript把它們一起拋入一個(gè)公共的全局命名空間中。附錄A有更多關(guān)于全局變量的內(nèi)容。
當(dāng)var語句被用在函數(shù)的內(nèi)部時(shí),它定義了這個(gè)函數(shù)的私有變量。
switch、while、for和do語句允許有一個(gè)可選的前置標(biāo)簽(label),它配合break語句來使用。
語句往往按照從上到下的順序被執(zhí)行。JavaScript可以通過條件語句(if和switch)、循環(huán)語句(while、for和do)、強(qiáng)制跳轉(zhuǎn)語句(break、return和throw)和函數(shù)調(diào)用來改變這個(gè)執(zhí)行序列。
代碼塊是包在一對花括號(hào)中的一組語句。不像許多其他的語言,JavaScript中的代碼塊不會(huì)創(chuàng)建一個(gè)新的作用域,因此變量應(yīng)該被定義在函數(shù)的頂端,而不是在代碼塊中。
if語句根據(jù)表達(dá)式的值改變程序的控制流程。如果表達(dá)式的值為真,那么執(zhí)行then代碼塊,否則,執(zhí)行可選的else分支。
下面列出的值被當(dāng)作假:
fase
null
undefined
數(shù)字0
數(shù)字NaN
其他所有的值都被當(dāng)作真,包括true,字符串”false”,以及所有的對象。
switch語句執(zhí)行一個(gè)多路分支。它把其表達(dá)式的值和所有指定的case條件進(jìn)行匹配。其表達(dá)式可能產(chǎn)生一個(gè)數(shù)字或字符串。當(dāng)找到一個(gè)精確的匹配時(shí),執(zhí)行匹配的case從句中的語句。如果沒有找到任何匹配,則執(zhí)行可選的default語句。
一個(gè)case從句包含一個(gè)或多個(gè)case表達(dá)式。case表達(dá)式不一定必須是常量。為了防止繼續(xù)執(zhí)行下一個(gè)case,case語句后應(yīng)該跟隨一上強(qiáng)制跳轉(zhuǎn)語句。你可以用break語句去退出一個(gè)switch語句。
while語句執(zhí)行一個(gè)簡單的循環(huán)。如果表達(dá)式值為假,那么循環(huán)將終止。而當(dāng)表達(dá)式值為真時(shí),代碼塊將被執(zhí)行。
for語句是一個(gè)結(jié)構(gòu)更復(fù)雜的循環(huán)語句。它有兩種形式。
常見的形式由三個(gè)可選從句控制:初始化從句(initialization)、條件從句(condition)和增量從句(increment)。首先,;初始化從句被執(zhí)行,它的作用通常是初始化循環(huán)變量。接著計(jì)算條件從句的值。典型的情況是它根據(jù)一個(gè)完成條件檢測循環(huán)變量。如果條件從句被省略掉,則假定返回的條件是真。如果條件從句的值為假,那么循環(huán)將終止。否則,執(zhí)行代碼塊,然后執(zhí)行增量從句,接著循環(huán)會(huì)重復(fù)執(zhí)行條件從句。
另一種形式(被稱為for in語句)會(huì)枚舉一個(gè)對象的所有屬性名(或鍵名)。在每次循環(huán)中,對象的另一個(gè)屬性名字符串被賦值給for和in之間的變量。
通常你須通過檢測object.hasOwnProperty(variable)來確定這個(gè)屬性名就是該對象的成員,還是從其原型鏈里找到的。
復(fù)制代碼 代碼如下:

for(myvar in obj){
if(obj.hasOwnProperty(myvar)){

}
}

do語句就像while語句,唯一的區(qū)別是它在代碼塊執(zhí)行之后而不是之前檢測表達(dá)式的值。這就意味著代碼塊將總是要執(zhí)行至少一次。
try語句執(zhí)行一個(gè)代碼塊,并捕獲該代碼塊拋出的任何異常。catch從句定義了一個(gè)新的變量,它將接收該異常對象。
throw語句拋出一個(gè)異常。如果throw語句在一個(gè)try代碼塊中,那么控制權(quán)會(huì)跳到catch從句中。如果throw語句在函數(shù)中,則該函數(shù)調(diào)用被放棄,且控制權(quán)會(huì)跳到調(diào)用該函數(shù)的try語句的catch從句中。
throw語句中的表達(dá)式通常是一個(gè)對象字面量,它包含一個(gè)name屬性和一個(gè)message屬性。異常捕獲器可以使用這些信息去決定該做什么。
return語句會(huì)使一人函數(shù)提前返回。它也可以指定要被返回的值。如果沒有指定返回表達(dá)式,那么其返回值是undefined。
JavaScript不允許在return關(guān)鍵字和表達(dá)式之間換行。
break語句會(huì)使程序退出一個(gè)循環(huán)語句或switch語句。它可以指定一個(gè)可選的標(biāo)簽,那將會(huì)使程序退出帶該標(biāo)簽的語句。
JavaScript不允許在break關(guān)鍵字和標(biāo)簽之間換行。
一個(gè)expression語句可以給一個(gè)或多個(gè)變量或成員賦值,或者調(diào)用一個(gè)方法,或者從對象中刪除一個(gè)屬性。運(yùn)算符=被用于賦值。不要把它和恒等運(yùn)算符===混淆。運(yùn)算符+=可以用于加法運(yùn)算或連接字符串。
2.6 表達(dá)式
三元運(yùn)算符?有三個(gè)運(yùn)算數(shù)。如果第一個(gè)運(yùn)算數(shù)值為真,它產(chǎn)生第二個(gè)運(yùn)算數(shù)的值。但是,如果第一個(gè)運(yùn)算數(shù)為假,它會(huì)產(chǎn)生第三個(gè)運(yùn)算數(shù)的值。
表2-1:運(yùn)算符優(yōu)先級
.[]()
屬性存取及函數(shù)調(diào)用
delete new typeof +-!
一元運(yùn)算符
*/%
乘法、除法、取模
+-
加法/連接、減法
>= <= > <
不等式運(yùn)算符
=== !==
等式運(yùn)算符
&&
邏輯與
||
邏輯或
?:
三元
typeo運(yùn)算符產(chǎn)生的值有'number'、'string'、'boolean'、'undefined'、'function'、'object'。如果運(yùn)算數(shù)是一個(gè)數(shù)組或null,那么結(jié)果是'object',這是不對的。第6章和附錄A將會(huì)有更多關(guān)于typeof的內(nèi)容。
/運(yùn)算符可能會(huì)產(chǎn)生一個(gè)非整數(shù)結(jié)果,即使兩個(gè)運(yùn)算數(shù)都是整數(shù)。
函數(shù)調(diào)用引發(fā)函數(shù)的執(zhí)行。函數(shù)調(diào)用運(yùn)算符是跟隨在函數(shù)名后面的一對圓括號(hào)。圓括號(hào)中可能包含將會(huì)傳遞給這個(gè)函數(shù)的參數(shù)。第4章將會(huì)有更多關(guān)于函數(shù)的內(nèi)容。
一個(gè)屬性存取表達(dá)式用于指定一個(gè)對象或數(shù)組的屬性或元素。下一章我將詳細(xì)描述它。
2.7 字面量
對象字面量是一種方便指定新對象的表示法。屬性名可以是標(biāo)識(shí)符或字符串。這些名字被當(dāng)作字面量名而不是變量名來對待,所以對象的屬性名在編譯時(shí)才能知道。屬性的值就是表達(dá)式。下一章將會(huì)有更多關(guān)于對象字面量的信息。
數(shù)組字面量是一個(gè)方便指定新數(shù)組的表示法。第6章將會(huì)有更多關(guān)于數(shù)組字面量的內(nèi)容。
第7章將會(huì)有更多關(guān)于正則表達(dá)式的內(nèi)容。
函數(shù)字面量定義了函數(shù)值。它可以有一個(gè)可選的名字,用于遞歸地調(diào)用自己。它可以指定一個(gè)參數(shù)列表,這些參數(shù)將作為變量由調(diào)用時(shí)傳遞的實(shí)際參數(shù)(arguments)初始化。函數(shù)的主體包括變量定義和語句。第4章將會(huì)有更多關(guān)于函數(shù)的內(nèi)容。

相關(guān)文章

最新評論