文檔javascript 王者歸來_第1頁
文檔javascript 王者歸來_第2頁
文檔javascript 王者歸來_第3頁
文檔javascript 王者歸來_第4頁
文檔javascript 王者歸來_第5頁
已閱讀5頁,還剩60頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、 JavaScript 王者歸來作者:月影清華大學(xué)第一部分概論第一章 從零開始程序設(shè)計之道無遠(yuǎn)弗屆,御晨風(fēng)而返杰弗瑞詹姆士在人類漫漫的歷史長河里,很難找到第二個由簡單邏輯和抽象符號組合而成的,具有如此宏大信息量和豐富多彩內(nèi)涵的領(lǐng)域。從某種意義上說,當(dāng)你翻開這本書的時候,你已經(jīng)踏入了一個任由你制定規(guī)則的未知世界。盡管你面對的僅僅是程序設(shè)計領(lǐng)域的冰山一角,但你將透過它,去領(lǐng)悟“道”的奧秘。在接下來的一段時間內(nèi),你會同我一起,掌握一種簡單而優(yōu)雅的神秘語言,學(xué)會如何將你的意志作用于它。這種 語言中所蘊(yùn)涵著的亙古之力,將為你開啟通往神秘世界的大門1.1 為什么選擇 JavaScript?在一些人眼里,程

2、序設(shè)計是一件神秘而浪漫的藝術(shù)工作,對他們來說,一旦選定某種編程語言,就會像一個忠貞的信徒一樣堅持用它來完成任何事情,然而我不是浪漫的藝匠,大多數(shù)人也都不是,很多時候我們學(xué)習(xí)一種新技術(shù)的唯一目的,只是為了把手中的事情做得更好。所以,當(dāng)你面對一項陌生的技術(shù)時, 需要問的第一個問題往往是,我為什么選擇它,它對我來說,真的如我所想的那么重要嗎? 好,讓我們帶著問題開始。 1.1.1 用戶的偏好:B/S 模式如果你堅持站在專業(yè)人員的角度,你就很難理解為什么 B/S 模式會那么受歡迎。如果你是一個資深的程序員,有時候你甚至?xí)δ切?B/S 模式的東西有一點點。因為在你看來,瀏覽器、表單、DOM 和其他一切

3、與 B/S 沾邊的東西,大多是行為古怪而難以駕馭的。以你的經(jīng)驗,你會發(fā)現(xiàn)實現(xiàn)同樣的交互,用B/S 來做通常會比用任何一種客戶端程序來做要困難得多。 如果你嘗試站在用戶的角度,你會發(fā)現(xiàn)為什么大多數(shù)最終用戶對 B/S 模式卻是如此的青睞。至少你不必去下載和安裝一個額外的程序到你的電腦上,不必為反復(fù)執(zhí)行安裝程序而困擾,不必整天被新的升級補(bǔ)丁打斷工作,不必理會注冊表、磁盤空間和一切對普通用戶來說有點頭疼的概念。如果你的工作地點不是 固定的辦公室,你日常工作的 PC 也不是固定的一臺或者兩臺,那么,B/S 的意義對你而言或許比想象的 還要大。 總之,用戶的需求讓 B/S 模式有了存在的理由,而迅速發(fā)展的

4、互聯(lián)網(wǎng)技術(shù)則加速了 B/S 應(yīng)用的普及。隨著一些優(yōu)秀的 Web 應(yīng)用產(chǎn)品出現(xiàn),不但喚起了用戶和業(yè)內(nèi)對 Ajax 技術(shù)的關(guān)注,也令 Web 領(lǐng)域內(nèi)的一個曾經(jīng)被無數(shù)人忽視的腳本語言JavaScript 進(jìn)入了有遠(yuǎn)見的開發(fā)人員和 IT 經(jīng)理人的視線。于是在你的手邊,也多了現(xiàn)在這本教程。 1.1.2 在什么情況下用 JavaScript一路發(fā)展到今天,JavaScript 的應(yīng)用范圍已經(jīng)大大超出一般人的想象,但是,最初的 JavaScript 是作為嵌入瀏覽器的腳本語言而存在,而它所提供的那些用以表示 Web 瀏覽器窗口及其內(nèi)容的對象簡單實用,功能強(qiáng)大,使得 Web 應(yīng)用增色不少,以至于直到今天,在大

5、多數(shù)人眼里,JavaScript 表現(xiàn)最出色的領(lǐng)域依然是用戶的瀏覽器,即我們所說的 Web 應(yīng)用的客戶端??蛻舳藶g覽器的 JavaScript 應(yīng)用也正是本書討論的重點內(nèi)容。 作為一名專業(yè)程序員,當(dāng)你在面對客戶的時候,經(jīng)常需要判斷哪些交互需求是適合于 JavaScript 來實現(xiàn)的。而作為一名程序愛好者或者是網(wǎng)頁設(shè)計師,你也需要了解哪些能夠帶給人驚喜的特效是能夠由JavaScript 來實現(xiàn)的。總之一句話,除了掌握 JavaScript 本身,我們需要學(xué)會的另一項重要技能是,在正確的時候、正確的地方使用 JavaScript。對于 JavaScript 初學(xué)者來說學(xué)會判斷正確使用的時機(jī)有時候甚

6、至比學(xué)會語言本身更加困難。 作為項目經(jīng)理,我經(jīng)常接受來自客戶的抱怨。因此我很清楚我們的 JavaScript 在帶給客戶好處的同時制造了太多的麻煩,相當(dāng)多的是由被錯誤使用的 JavaScript 引起的。一些代碼本不應(yīng)該出現(xiàn)在那個位置,而另一些代碼則根本就不應(yīng)當(dāng)出現(xiàn)。我曾經(jīng)尋訪過問題的根源,發(fā)現(xiàn)一個主要的原因由于 JavaScript的過于強(qiáng)大(在后面的小節(jié)中我們將會提到,另一個同樣重要的原因是“腳本誘惑”),甚至超越了瀏覽器的制約范圍,于是麻煩就不可避免的產(chǎn)生了,這就像你將一個放入一個根本就不可能關(guān)住它的盒子 里,那么你也就無法預(yù)料會做出任何超出預(yù)期的舉動。 在什么情況下用 JavaScri

7、pt?給出一個簡單的答案是:在任何不得不用的場合使用,除此以外,不要在任何場合使用!無懈可擊的應(yīng)用是不用,除非你確實無法找到一個更有效更安全的替代方案。也許這個答案會讓讀到這里的讀者有些郁悶,但是,我要很嚴(yán)肅地提醒各位,由于 JavaScript 比大多數(shù)人想象的要復(fù)雜和強(qiáng)大得多,所以它也比大多數(shù)人想象得要危險得多。在我的朋友圈子里,許多資深的 JavaScript 程序員(包括我在內(nèi))偶爾也不得不為自己一時疏忽而做出的錯誤決定讓整個項目團(tuán)隊在“腳本泥潭”中掙扎好一陣子。所以這個建議從某種意義上說也是專家們的血淚教訓(xùn)。最后向大家陳述一個令人欣慰的事實, 即使是像前面所說的這樣,在 Web 應(yīng)用

8、領(lǐng)域,JavaScript 的應(yīng)用范圍也仍然是相當(dāng)廣泛的。 在本節(jié)的最后三個小節(jié)里,我們將進(jìn)一步展開討論關(guān)于 JavaScript 使用的話題。毫無疑問,正確的做法是:不要放出。所以,JavaScript 程序員需要學(xué)會的第一個技巧就是掌握在什么情況下使用 JavaScript 才是安全的。 編寫本書的時候,在 TIOBE 編程社區(qū)最新公布的數(shù)據(jù)中,JavaScript 在世界程序開發(fā)語言中排名第十, 這意味著 JavaScript 已經(jīng)正式成為一種被廣泛應(yīng)用的熱門語言。 大多數(shù)情況下,客戶更偏好使用瀏覽器,而不是那些看起來比較專業(yè)的軟件界面,專業(yè)人員則恰恰相反。 1.1.3 對 JavaSc

9、ript 的一些誤解JavaScript 是一個相當(dāng)容易誤解和混淆的主題,因此在對它進(jìn)一步研究之前,有必要澄清一些長期存在的有關(guān)該語言的誤解。 JavaScript 和 Java這是最容易引起誤會的一個地方,這個 Java-前綴似乎暗示了 JavaScript 和 Java 的關(guān)系,也就是JavaScript 是 Java 的一個子集。看上去這個名稱就故意制造混亂,然后隨之而來的是誤解。事實上,這兩種語言是完全不相干的。 盡管 JavaScript 和 Java 完全不相干,但是事實上從某種程度上說它們是很好的搭檔。JavaScript 可以控制瀏覽器的行為和內(nèi)容,但是卻不能繪

10、圖和執(zhí)行連接(這一點事實上并不是絕對的,通過模擬是可以做到的)。而 Java 雖然不能在總體上控制瀏覽器,但是卻可以繪圖、執(zhí)行連接和多線程。客戶端的 JavaScript 可以和嵌入網(wǎng)頁的 Java applet 進(jìn)行交互,并且能夠?qū)λ鼒?zhí)行控制,從這一意義上來說,JavaScript 真的可以腳本化 Java。 披著 C 外衣的 LispJavaScript 的 C 風(fēng)格的語法,包括大括號和復(fù)雜的 for 語句,讓它看起來好像是一個普通的過程式語言。這是一個誤導(dǎo),因為 JavaScript 和函數(shù)式語言如 Lisp 和 Scheme 有更多的共同之處。它用數(shù)組代替了列表,用對象

11、代替了屬性列表。函數(shù)是第一型的。而且有閉包。你不需要平衡那些括號就可以用 算子。 關(guān)于 JavaScript 閉包和函數(shù)式的內(nèi)容,在本書的第 23 章中會有更詳細(xì)的介紹。 思維定勢 JavaScript 是原被設(shè)計在Netscape Navigator 中運(yùn)行的。它的成功讓它成為幾乎所有瀏覽器的標(biāo)準(zhǔn)配置。這導(dǎo)致了思維定勢。認(rèn)為 JavaScript 是依賴于瀏覽器的腳本語言。其實,這也是一個誤解。JavaScript 也適合很多和 Web 無關(guān)的應(yīng)用程序。 業(yè)余愛好者 一個很糟糕的認(rèn)知是:JavaScript 過于簡樸,以至于大部分寫 JavaScript 的人都

12、不是專業(yè)程序員。他們?nèi)狈懞贸绦虻男摒B(yǎng)。JavaScript 有如此豐富的表達(dá)能力,他們可以任意用它來寫代碼,以任何形式。 事實上,上面這個認(rèn)知是曾經(jīng)的現(xiàn)實,不斷提升的 Web 應(yīng)用要求和 Ajax 徹底改變了這個現(xiàn)實。通過學(xué)習(xí)本書,你也會發(fā)現(xiàn),掌握 JavaScript 依然需要相當(dāng)高的專業(yè)程序員技巧,而不是一件非常簡單的事情。不過這個曾經(jīng)的現(xiàn)實卻給 JavaScript 帶來了一個壞名聲它是專門為外行設(shè)計的,不適合專業(yè)的程序員。 這顯然是另一個誤解。 推廣 JavaScript 最大的困難就在于消除專業(yè)程序員對它的偏見,在我的項目團(tuán)隊中許多有經(jīng)驗的 J2EE程序員卻對 JavaScript

13、 停留在一知半解甚至茫然的境地,他/她們不愿意去學(xué)習(xí)和掌握 JavaScript,認(rèn)為這門腳本語言是和瀏覽器打交道的美工們該干的活兒,不是正經(jīng)程序員需要掌握的技能。這對于 Web 應(yīng)用開發(fā) 早些年在學(xué)校的時候,我和我的實驗室搭檔曾經(jīng)研究過將 JavaScript 作為一種 PDA 控制芯片的動態(tài)腳 本語言的可行性,而在我們查閱資料的過程中發(fā)現(xiàn)一些對基于嵌入式環(huán)境的動態(tài)腳本語言實現(xiàn)的嘗試,我們有理由相信,JavaScript 在某些特定的嵌入式應(yīng)用領(lǐng)域中也能夠表現(xiàn)得相當(dāng)出色。 JavaScript 和 Java 的語法很相似,就像 Java 和 C 的語法相似一樣。但它不是 Java 的子集就像

14、 Java 也不是 C 的子集一樣。在應(yīng)用上,Java 要遠(yuǎn)比原先設(shè)想的好得多(Java 原稱 Oak)。 JavaScript 的創(chuàng)造者是 Brendan Eich,最早的版本在 NetScape 2 中實現(xiàn)。在編寫本書時,Brendan Eich在 Mozilla 公司任職,他本人也是 JavaScript 的主要革新者。而更加有名的 Java 語言,則是出自 Sun Microsystems 公司的杰作。 JavaScript 最初叫做 LiveScript,這個名字本來并不是那樣容易混淆,只是到最后才被改名為 JavaScript,據(jù)說起同 Java 相似的名字純粹是一種行銷策略。 1

15、.1.3.5 面向?qū)ο?JavaScript 是不是面向?qū)ο蟮??它擁有對象,可以包含?shù)據(jù)和處理數(shù)據(jù)的方法。對象可以包含其它對象。它沒有類(在 JavaScript 2.0 真正實現(xiàn)之前),但它卻有構(gòu)造器可以做類能做的事,包括扮演類變量和方法的容器的角色。它沒有基于類的繼承,但它有基于原型的繼承。兩個建立對象系統(tǒng)的方法是通過繼承和通過聚合。JavaScript 兩個都有,但它的動態(tài)性質(zhì)讓它可以在聚合上超越。 一些批評說 JavaScript 不是真正面向?qū)ο蟮囊驗樗荒芴峁┬畔⒌碾[藏。也就是,對象不能有私有變量和私有方法:所有的成員都是公共的。但隨后有人證明了 JavaScript 對象可以擁有

16、私有變量和私有方法。另外還有批評說 JavaScript 不能提供繼承,但隨后有人證明了 JavaScript 不僅能支持傳統(tǒng)的繼承還能應(yīng)用其 它的代碼復(fù)用模式。 關(guān)于 JavaScript 面向?qū)ο蟮膬?nèi)容,在本書的第 21 章中會有更詳細(xì)的介紹。 其他誤解 除了以上提到的幾點之外,JavaScript 還有許多容易令人迷惑和誤解的特性,這些特性使得 JavaScript成為世界上最被誤解的編程語言。 如果讀者對這方面有興趣,可以詳細(xì)閱讀下面這篇文章/javascript.htmlDouglas Crockford1.1

17、.4 警惕!腳本誘惑前面我們提到過,許多專業(yè)程序員拒絕去了解如何正確使用 JavaScript,另一些則是缺乏對 JavaScript 足夠的認(rèn)知和應(yīng)用經(jīng)驗。但是在 B/S 應(yīng)用中,相當(dāng)多的情況下,要求開發(fā)人員不得不采用 JavaScript。于是,一個問題產(chǎn)生了,大量的 JavaScript 代碼拷貝出現(xiàn)在頁面的這個或者那個地方,其中的大部分是不必要的,另一部分可能有缺陷。我們的開人員沒有辦法(也沒有意識到)去判斷這些代碼是否必要,以及使 用它們會帶來哪些問題。 由于瀏覽器的 JavaScript 可以方便地被復(fù)制粘貼,因此,一個特效或者交互方式往往在真正評估它的必要性之前便被采用客戶想要它

18、,有人使用過它,程序員復(fù)制它,而它就出現(xiàn)在那兒,表面上看起來很完美,于是,所謂的腳本誘惑就產(chǎn)生了。 事實上,在我們真正使用 JavaScript 之前,需要反復(fù)問自己一個重要問題是,究竟是因為有人想要它,還是因為真正有人需要它。在你駕馭 JavaScript 馬車之前,你必須學(xué)會要的地方,永遠(yuǎn)保持你的 Web 界面簡潔,風(fēng)格一致。 腳本誘惑,把你的腳本用在必 在用戶眼里,簡潔一致的風(fēng)格與提供強(qiáng)大而不常用的功能和看起來很 COOL 而實際上沒有什么功用的 界面特效相比起來,前者更能令他們覺得專業(yè)。畢竟,大部分用戶和你我一樣,掌握一個陌生的環(huán)境和新的技能只是為了能夠?qū)⑹虑樽龅酶旄?。除非你要提?/p>

19、的是一個類似于 Qzone 之類的娛樂程序,你永遠(yuǎn)也不要大量地使用不必要的 JavaScript。 如果你的 B/S 應(yīng)用中的 JavaScript 不是由專業(yè)的 JavaScript 程序員來維護(hù)的,那么當(dāng)你對你的開發(fā)團(tuán)隊 進(jìn)行一次小小的代碼走查時,你甚至可能會發(fā)現(xiàn) 90%的 JavaScript 代碼被錯誤地使用,這些錯誤使用的代碼浪費(fèi)了用戶大量的網(wǎng)絡(luò)帶寬、內(nèi)存和 CPU 資源,提升了對客戶端配置的要求,降低了系統(tǒng)的穩(wěn)定性, 甚至導(dǎo)致許多本來可以避免的安全問題。 說 JavaScript 是一種基于對象的語言,是一種正確而略顯保守的判斷,而說 JavaScript 不面向?qū)ο螅?在我看來則

20、是錯誤的認(rèn)知。事實上有充足的理由證明 JavaScript 是一種的面向?qū)ο蟮恼Z言,只是與傳統(tǒng)的 class-based OO(基于類的面向?qū)ο螅┫啾?,JavaScript 有它與眾不同的地方,這種獨特性我們稱它為 prototype-based OO(基于原型的面向?qū)ο螅?來說,無疑是一個相當(dāng)不利的因素。 1.1.5 隱藏在簡單表象下的復(fù)雜度專業(yè)人員不重視 JavaScript 的一個重要原因是,他們覺得 JavaScript 是如此的簡單,以至于不愿意花精力去學(xué)習(xí)(或者認(rèn)為不用學(xué)習(xí)就能掌握)。前面提到過的,這實際上是一種誤解。事實上,在腳本語言中, JavaScript 屬于相當(dāng)復(fù)雜的一

21、門語言,它的復(fù)雜程度未必遜色于 Perl 和Python。 之所以很多人覺得 JavaScript 過于簡單,是因為他們大量使用的是一些 JavaScript 中看似簡單的文法, 解決的是一些看似簡單的問題,真正復(fù)雜而又適合 JavaScript 的領(lǐng)域卻很少有人選擇 JavaScript,真正強(qiáng)大的用法很少被涉及。JavaScript 復(fù)雜的本質(zhì)被一個個簡單應(yīng)用的表象所隱藏。 我曾經(jīng)給一些堅持認(rèn)為 JavaScript 過于簡單的開發(fā)人員寫過一段小代碼,結(jié)果令他們中的大部分內(nèi)行人大驚失色,那段代碼看起來大致像下面這個樣子: var a = -1,-1,1,-3,-3,-3,2,2,-2,-2

22、,3,-1,-1;function f(s, e)var ret = ;for(var i)ret.push(e(si);return ret;var b = f(a, function(n)return n0?n:0); alert(b);因為這段代碼而尖叫的不僅僅包括我的這些程序員朋友,事實上,更興奮的是另一些電子領(lǐng)域的朋友, 他們寫信給我反饋說,在此之前他們從來沒有見到過如此形式簡潔而優(yōu)雅的數(shù)字高通濾波器,更令人欣喜的是,它的閾值甚至是可調(diào)節(jié)的: var b = f(a, function(n)return n=-1?n:0); 如果你想要,它也很容易支持低通濾波: var b = f(

23、a, function(n)return n0?n:0);用一個小小的堆?;蛘咂渌總z,你也可以構(gòu)造出一族差分或者其他更為復(fù)雜的數(shù)字設(shè)備,而它們明顯形式相近并且結(jié)構(gòu)優(yōu)雅。 總之,不要被簡單的表象所迷惑,JavaScript 的復(fù)雜度往往很大程度上取決于你的設(shè)計思路和你的使 用技巧。JavaScript 的確是一門可以被復(fù)雜使用的程序設(shè)計語言。 1.1.6 令人迷惑的選擇:錦上添花還是雪中送炭本節(jié)最后的這個話題在前面已經(jīng)被隱諱地提到過多次,實際上,本小節(jié)圍繞的話題依然是什么時候使用 JavaScript。一種比較的觀點是在必須的時候采用,也就是前面所說的不得不用的場合,另一種比這是本書中出現(xiàn)的第

24、一段 JavaScript 代碼,也許現(xiàn)在你看來,它有那么一點點令人迷惑,但是不要緊, 在本書后面的章節(jié)中,你會慢慢理解這段代碼的含義以及它的無窮妙味。而現(xiàn)在你完全可以跳過它的實際內(nèi)容,只要需要知道這是一段外表看起來簡單的魔法代碼就夠了。 另一個業(yè)內(nèi)的偏見是腳本語言都是比較簡單的,實際上,一門語言是否腳本語言往往是它的設(shè)計目標(biāo) 決定的,簡單與復(fù)雜并不是區(qū)分腳本語言和非腳本語言的標(biāo)準(zhǔn)。JavaScript 即使放到非腳本語言中來衡量, 也是一門相當(dāng)復(fù)雜的語言。 較溫和一點的觀點則堅持在需要的時候使用,這種觀點認(rèn)為當(dāng)我們可以依靠 JavaScript 令事情變得更好的時候,我們就采用它。 事實上,

25、就我個人而言,比較支持“必須論”,這是因為從我以往的經(jīng)驗來看,JavaScript 是難以駕馭的,太多的問題由使用 JavaScript 不當(dāng)而產(chǎn)生,其中的一部分相當(dāng)令人困擾,徹底解決它們的辦法就是盡可能降低 JavaScript 的使用頻率,也盡可能將它用在真正適合它的地方。當(dāng)然萬事沒有絕對,在何時使用 JavaScript 永遠(yuǎn)是一個難題,然而不管怎么說同“錦上添花”相比,JavaScript 程序員也許應(yīng)當(dāng)更多考慮 的是如何“雪中送炭”。 1.1.7 回到問題上來本節(jié)要解決的問題是為什么選擇 JavaScript,然而在相當(dāng)多的篇幅里,我們都在試圖尋找一些少用和不用 JavaScript

26、 的理由,盡管如此,拋開大部分不適合 JavaScript 的位置和時機(jī),瀏覽器上依然會經(jīng)常地見 到 JavaScript 的身影,對于瀏覽器來說,JavaScript 實在是一個不可缺少的修飾。 最后,用一句話小結(jié)本節(jié)的內(nèi)容我們之所以選擇 JavaScript,是因為:Web 應(yīng)用需要 JavaScript,我們的瀏覽器、我們的程序員和我們的用戶離不開它。 1.2 JavaScript 的應(yīng)用范圍我記得在前面依稀提到過,JavaScript 的應(yīng)用范圍相當(dāng)廣泛,除了最常見的客戶端瀏覽器之外, JavaScript 還被應(yīng)用在一部分服務(wù)器端的環(huán)境、桌面程序和其他一些應(yīng)用環(huán)境中。 1.2.1 客

27、戶端的 JavaScript目前絕大多數(shù)瀏覽器中都嵌入了某個版本的 JavaScript 解釋器。當(dāng) JavaScript 被嵌入客戶端瀏覽器后, 就形成了客戶端的 JavaScript。這是迄今為止最常見也最普通的 JavaScript 變體。大多數(shù)人提到 JavaScript時,通常指的是客戶端的 JavaScript,本書重點介紹的內(nèi)容,也是 JavaScript 的客戶端應(yīng)用。 在后面的章節(jié)中提到的“瀏覽器中的 JavaScript”通常也是特指客戶端的 JavaScript。當(dāng)一個 Web 瀏覽器嵌入了 JavaScript 解釋器時,它就允許可執(zhí)行的內(nèi)容以 JavaScript 的

28、形式在用戶客戶端瀏覽器中運(yùn)行。下面的例子展示了一個簡單的嵌入網(wǎng)頁中的 JavaScript 程序。 例 1.1 經(jīng)典程序 Hello World! 的 JavaScript 實現(xiàn) Example 1.1 Hello World!你再也找不到任何一種優(yōu)雅簡樸的腳本語言如此適合于在瀏覽器中生存。在本書的第 2 章,我們將具體接觸嵌入瀏覽器中的 JavaScript。 您的瀏覽器不支持 JavaScript,請檢查瀏覽器版本或者安全設(shè)置,謝謝!第一個例子展示了 document.write 是瀏覽器提供的一個方法,用來向 document 文檔對象輸出內(nèi)容, 至于什么是文檔對象,在本書的第三部分將有

29、詳細(xì)的介紹。把這個腳本裝載進(jìn)一個啟用 JavaScript 的瀏覽器后,就會產(chǎn)生如圖 1.1 所示的輸出。 圖 1.1 Hello World如果你看到的是“您的瀏覽器不支持 JavaScript”的字樣,那么需要檢查瀏覽器的版本和安全設(shè)置,以確定你的瀏覽器正確支持 JavaScript。 從例子中可以看到,標(biāo)記和是用來在 HTML 中嵌入 JavaScript 代碼的。我們將在第 2 章和第 22 章中了解更多有關(guān)標(biāo)記的內(nèi)容。在這個例子中,方法 document.write()用來向 HTML 文檔輸出文本,在本書的后續(xù)章節(jié)中,我們會多次見到它。 JavaScript 當(dāng)然不僅僅是用來簡單地

30、向 HTML 文檔輸出文本內(nèi)容的,事實上它可以控制大部分瀏覽器相關(guān)的對象,瀏覽器為 JavaScript 提供了強(qiáng)大的控制能力,使得它不僅能夠控制 HTML 文檔的內(nèi)容,而且能夠控制這些文檔元素的行為。在后面的章節(jié)里,我們會了解到 JavaScript 通過瀏覽器對象接口訪問和控制瀏覽器元素,通過 DOM 接口訪問和控制 HTML 文檔,通過給文檔定義“戶觸發(fā)的交互行為。 處理器”的方式響應(yīng)由用 小技巧:和是一種防御性編碼,如果用戶的瀏覽器不支持 JavaScript 或者設(shè)置了 過高的安全級別,那么就會顯示出相應(yīng)的提示信息,避免了在用戶不知情的情況下停止運(yùn)行或者得到錯誤結(jié)果。 1.2.2 服

31、務(wù)器端的 JavaScript相信大多數(shù)人對客戶端執(zhí)行的 JavaScript 并不陌生,而服務(wù)器端的 JavaScript 就鮮有人知了。不少應(yīng)用服務(wù)器提供了對 JavaScript 的支持,比較典型的如 Microsoft 的 IIS,還有一些版本的 Java 應(yīng)用服務(wù)器提供 了在 Servlet 容器中執(zhí)行 JavaScript 的能力。 1.2.3 其他環(huán)境中的 JavaScript除了 Web 應(yīng)用的相關(guān)領(lǐng)域之外,JavaScript 還能夠在多種不同的環(huán)境中運(yùn)行。在較早一些的時候,Microsoft 已經(jīng)在 Windows 系統(tǒng)中支持一種 HTA 應(yīng)用,這可以看作是由 JavaSc

32、ript + HTML 編寫的類似 GUI的應(yīng)用程序。在.net framework 的新版本中,Microsoft 更是直接支持了 J。 前面也提到過 Mozilla 組織提供的開源 JavaScript 解釋器,實際上 Microsoft 公司和 Netscape 公司都向那些想把 JavaScript 解釋器嵌入自己應(yīng)用程序的公司和設(shè)計者開放了它們的 JavaScript 解釋器。所以如果程序員在其他應(yīng)用中需要 JavaScript 的支持,可以比較容易地獲得 JavaScript 解釋器的不同版本。隨著計算機(jī)技術(shù)的發(fā)展,越來越多的應(yīng)用程序?qū)⒛撤N動態(tài)語言作為嵌入式腳本

33、以增強(qiáng)系統(tǒng)的交互能力和擴(kuò)展性,我們有理由相信,在可選擇的動態(tài)語言中,JavaScript 是一種非常優(yōu)秀的備選方案。我們期待著看到越來越多 的應(yīng)用程序?qū)?JavaScript 作為嵌入式腳本語言。 1.3 JavaScript 的版本JavaScript 和其他的一些腳本語言一樣,有著各種各樣的實現(xiàn)版本,雖然早在 JavaScript1.3 實現(xiàn)的時候 (大約是 1999 年 12 月),ECMA 組織已經(jīng)標(biāo)準(zhǔn)化了 EVMAScript v1 版本,但是,如同 ECMA 組織努力地標(biāo)準(zhǔn)化一樣,JavaScript 從來也沒有停止過它基于各種不同瀏覽器的差異化發(fā)展。一方面這種差化 JavaScr

34、ipt 給開發(fā)者帶來了不小的困擾,然而另一方面這種百花齊放式的差異化發(fā)展也將越來越多的優(yōu)秀特性加入到JavaScript 中,最終使得 JavaScript 迅速發(fā)展成為一種強(qiáng)大而優(yōu)秀的腳本語言。 應(yīng)用程序支持腳本語言已經(jīng)成為一種趨勢。例如在 WinCVS 中直接引入了 Python 作為命令行腳本擴(kuò)展,但那還不是一種真正的嵌入式腳本實現(xiàn)。在 AutoCAD 中引入了 Lisp 作為嵌入式腳本語言,而 LabView 則有自己的類 C 腳本實現(xiàn)。相對更為著名的 ActionScript 是 Macromedia 公司的 Flash 中所支持的動態(tài)腳本語言,有趣的是,ActionScript 是

35、在 ECMAScript 標(biāo)準(zhǔn)發(fā)布后被模型化的,在后面的章節(jié)里,你會了解到ECMAScript 實際上是標(biāo)準(zhǔn)化的 JavaScript。不過,有些遺憾的是,ActionScript 并不是真正的 JavaScript。 J 是一個較少人知的,Microsoft 并未在 Visual S 中集成 J 的可視化編輯 器,卻將 J 在.net 的核心環(huán)境中實現(xiàn)了。J 可以看作是一種 CLR 托管的 JavaScript,實際上是.net 的一種編程語言實現(xiàn)。安裝了較新版本的.net framework

36、的讀者可以試著編寫 J 并在命令行中編譯執(zhí)行,有關(guān) J 的更多內(nèi)容可參考 Microsoft 的官方文檔。 在基于 IIS 的 asp 應(yīng)用中,將一段 JavaScript 聲明為服務(wù)器端代碼,只需要在標(biāo)簽中指定屬性 runat = server,這樣,這段代碼將會在服務(wù)器端被執(zhí)行。 Netscape 開發(fā)了一套用 Java 實現(xiàn)的 JavaScript1.5 解釋器,它是作為開放資源發(fā)布的,被稱為 Rhino, 目前通過 Mozilla 組織可以得到它。事實上正是 Rhino 的存在向 Java 應(yīng)用服務(wù)器提供了容器對 JavaScript 的支持。另

37、一套同樣由 Mozilla 組織提供的 JavaScript1.5 解釋器是用 C 語言實現(xiàn)的,被稱為 SpiderMonkey。 1.3.1 瀏覽器中的 JavaScript 版本JavaScript 語言已經(jīng)發(fā)展幾年了,Netscape 公司發(fā)布了該語言的多個版本。Microsoft JavaScript 語言的相應(yīng)版本,名為 Jscript。表 1.1 列出了這些版本 表 1.1 JavaScript 的版本 公司也發(fā)布了1.3.2 其他版本ECMA(http:/www.ecma.ch)組織發(fā)布了三個版本的 ECMA-262 標(biāo)準(zhǔn),該標(biāo)準(zhǔn)標(biāo)準(zhǔn)化了 JavaScript 語言。ECMA 組

38、織還整理了 ECMAScript 的第 4 個版本(/js/language/es4/index.html)。幾乎同一時間 Mozilla 組織開始設(shè)計 JavaScript 2.0,在本書開始編寫的時候,還未聽說 ECMAScript v4 和 JavaScript 2.0 在任何瀏覽器上實現(xiàn)。表 1.2 列出了 ECMAScript 的標(biāo)準(zhǔn)化版本和 JavaScript 2.0 。 表 1.2 ECMAScript 標(biāo)準(zhǔn)化版本和 Mozilla JavaScript 2.0在本書的第 19 章里,將會更加詳細(xì)地談到這些版本和標(biāo)準(zhǔn)的相關(guān)內(nèi)容。版本 說

39、明 ECMA v1該語言的第一個標(biāo)準(zhǔn)版本,標(biāo)準(zhǔn)化了 JavaScript 1.1 的基本特性,并添加了一些新特性,沒有標(biāo)準(zhǔn)化switch 語句和正則表達(dá)式。與JavaScript1.3 和 Jscript3.0 的實現(xiàn)一致 ECMA v2該標(biāo)準(zhǔn)的維護(hù)版本,添加了說明,但沒有定義任何新特性 ECMA v3標(biāo)準(zhǔn)化了 switch 語句、正則表達(dá)式和異常處理,與 JavaScript 1.5 和 Jscript 5.5 的實現(xiàn)一致 ECMA v4增加了強(qiáng)類型、名字空間、類修飾符、操作符重載等,極大強(qiáng)化了 JavaScript 面向?qū)ο蟮哪芰?JavaScript 2.0本書編寫的時候還未見在任何瀏覽

40、器上實現(xiàn)的 JavaScript 未來版本,完全符合 ECMA v4,并增加了 include 語句 版本 說明 JavaScript 1.0該語言的原始版本,目前已經(jīng)基本上被廢棄。由 Netscape 2 實現(xiàn) JavaScript 1.1引入了真正的 Array 對象,消除了大量重要的錯誤。由 Netscape 3 實現(xiàn) JavaScript 1.2引入了 switch 語句、正則表達(dá)式和大量其他特性,基本上符合 ECMA v1,但是還有一些不兼容性,由 Netscape 4 實現(xiàn) JavaScript 1.3修正了 JavaScript1.2 的不兼容性,符合 ECMA v1。由 Net

41、scape 4.5 實現(xiàn) JavaScript 1.4只在 Netscape 的服務(wù)器產(chǎn)品中實現(xiàn) JavaScript 1.5引入了異常處理,符合 ECMA v3。由 Netscape 6 實現(xiàn) Jscript 1.0基本上相當(dāng)于 JavaScript 1.0,由 IE 3 的早期版本實現(xiàn) Jscript 2.0基本上相當(dāng)于 JavaScript 1.1,由 IE 3 的后期版本實現(xiàn) Jscript 3.0基本上相當(dāng)于 JavaScript 1.3,符合 ECMA v1。由 IE 4 實現(xiàn) Jscript 4.0沒有任何瀏覽器實現(xiàn)它 Jscript 5.0支持異常處理,部分符合 ECMA v3

42、。由 IE5 實現(xiàn) Jscript 5.5+基本上相當(dāng)于JavaScript 1.5。完全符合ECMA v3。IE 5.5 實現(xiàn)Jscript 5.5, IE 6 實現(xiàn) Jscript 5.6, IE 7 實現(xiàn) Jscript 5.7 1.4一些值得留意的特性JavaScript 為什么吸引著這么多的愛好者學(xué)習(xí)、研究和進(jìn)行開發(fā),一方面它確實擁有強(qiáng)大的功能,能夠支持你開發(fā)出優(yōu)秀的 Web 應(yīng)用產(chǎn)品,另一方面它也是有趣的,它的某些特性本身就能夠令人感受到某種樂趣。 1.4.1 小把戲:神奇的魔法代碼是什么使得 JavaScript 不同于其他程序設(shè)計語言,在瀏覽器修飾方面表現(xiàn)出其優(yōu)異的特性?毫無疑

43、問, JavaScript 在 Web 應(yīng)用領(lǐng)域受到的好評,既源于它自身靈活的動態(tài)特性,也源于瀏覽器對它充分的支持。 下面的這段代碼在網(wǎng)絡(luò)上廣為流傳,被眾多 JavaScript 愛好者奉為代表 JavaScript 魔力的經(jīng)典: 例 1.2 神奇的“魔法代碼” JavaScript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.images; DIL=DI.length; function A()for(i=0; i-DIL; i+)DIS=DI

44、i .style; DIS.position=absolute; DIS.left=Math.cos(R*x1+i*x2+x3)*x4+x5; DIS.top=Math.sin(R*y1+i*y2+y3)*y4+y5R+setInterval(A(),5); void(0);打開一個帶有幾張圖片的網(wǎng)頁(圖片稍微多一些并且每張圖片大小相當(dāng)?shù)脑?,效果會比較好),將上面這段代碼輸入到 IE 瀏覽器的地址欄(不要換行),敲回車,就會看到頁面上的所有圖片圍成一圈繞著一個點旋轉(zhuǎn)。事實上,這是一段有些故弄玄虛的指令,很容易讓初學(xué)者覺得新奇和迷惑,而對于資深的JavaScript 程序員來說,它幾乎恰如其分地

45、表現(xiàn)出了 JavaScript 大部分操作客戶端瀏覽器的特性(除了故意的糟糕排版和蹩腳的變量命名方式之外)。 在這里,我們先簡要地列舉一下這些特性,而具體的內(nèi)容將會在后續(xù)的章節(jié)里詳細(xì)展開。 首先,一些瀏覽器(不是所有的)支持JavaScript 偽協(xié)議,你可以在瀏覽器的地址欄里通過“JavaScript:” 的形式來執(zhí)行JavaScript代碼。實際上這種良好的執(zhí)行方式為JavaScript愛好者帶來了一個便捷的測試手段, 使得他們能夠以類似命令行的方式來簡易地測試一個沒有用過的 JavaScript 特性,而不必寫一大堆文本和HTML 標(biāo)簽。 其次,JavaScript 支持缺省聲明直接賦值

46、的方式來使用全局變量,唯一的約束是命名規(guī)則和保留字, 作為一種腳本語言,這個特性無疑提供了一種快速便利的執(zhí)行手段,缺點則也是很明顯的,缺乏嚴(yán)謹(jǐn)?shù)募s束,為不良代碼的產(chǎn)生提供了可能。 注意到 document.images 的用法,這個指令枚舉出頁面文檔中所有的圖片元素,并把這個元素集合的引用賦值給臨時變量 DI。 DI=document.images;Document 是一個非常有用的接口,它是 JavaScript 訪問頁面文檔對象的主要方式。除了訪問圖片的 大部分程序設(shè)計語言中,變量被設(shè)計為在聲明之后引用,也就是說,要使用某個對象,必須先告知該 對象存在之后才能賦值,即先“(在之中)有一個

47、A”,然后才能說“A 是一個”,在 JavaScript 中, 如果對象的作用域是全局的,則不強(qiáng)制要求“有一個 A”的聲明。關(guān)于變量定義和聲明的內(nèi)容,在第 4 章將會有詳細(xì)的討論。 作為程序員,如果你不管理好自己代碼里的變量,那么總有一天你或者你的繼任會為它們整天頭疼不已??赡艹霈F(xiàn)在任何地方的變量,像缺乏約束四處亂竄的野馬,隨時都可能導(dǎo)致整個系統(tǒng) 。一個好的習(xí)慣是用良好的自我約束來限制變量的定義和使用,并且避免定義過多的全局變量。在 JavaScript 中,利用閉包是一種代替臨時變量的好習(xí)慣,在后續(xù)的章節(jié)中,我們會詳細(xì)討論這些現(xiàn)在聽起來有些深奧的技巧。 JavaScript 是一種深受瀏覽器

48、“寵愛”的語言,瀏覽器為其提供了豐富的資源和廣闊的舞臺。 document.images 之外,document 提供的屬性還能夠方便地引用頁面文檔對象中的表單、鏈接和其他元素。document 接 口 還 提 供 了 一 組 更 為 標(biāo) 準(zhǔn) 的 方 法 來 創(chuàng) 建 和 訪 問 文 檔 元 素 , 它 們 是d o c u m e n t . g e t E l e m e n t B y I d 、 document.getElementsByTagName 和 document.createElement, 通常我們認(rèn)為以上三個方法是 document 對象提供的最主要的 DOM 接口。關(guān)

49、于 DOM 話題我們將會在第 12另一個需要重點關(guān)注的特性是函數(shù)定義,function A()聲明了一個名字叫做“A”的函數(shù),其后的一對大括號內(nèi)的指令是對這個函數(shù)的定義。提供函數(shù)文法使得 JavaScript 成為一種完善的過程式語言。 function A()for(i=0; i-DIL; i+)DIS=DI i .style; DIS.position=absolute; DIS.left=Math.cos(R*x1+i*x2+x3)*x4+x5; DIS.top=Math.sin(R*y1+i*y2+y3)*y4+y5R+在函數(shù)定義體內(nèi),我們可以看到像 Math.cos(R*x1+i*x

50、2+x3)這樣的用法,Math 是 JavaScript 的一個有用的內(nèi)置對象,它為 JavaScript 的使用者提供了一組有用的數(shù)學(xué)函數(shù),Math.cos 返回表達(dá)式的余弦值。 在這之后我們通過一個循環(huán)將數(shù)學(xué)計算的結(jié)果賦值給 document.images 集合中提供的圖片樣式屬性, 這里引用的是 style.top 和 style.left 屬性,這兩個屬性分別定義了圖片元素左上角距參照系原點的橫坐標(biāo)和縱坐標(biāo)的值,默認(rèn)的單位是像素點(關(guān)于元素的定位問題我們將會在后續(xù)的章節(jié)中有詳細(xì)的討論),這樣我們相當(dāng)于將頁面文檔中的圖片元素抽取出來,重新計算了它們的位置,并按照新的位置進(jìn)行排列。 最后,

51、我們在排列的過程中改變參量 R 的值,并通過定時器函數(shù) setInterval 每隔 5 個毫秒調(diào)用一次 A() 函數(shù),就實現(xiàn)了例子中的圖片旋轉(zhuǎn)的特效。 setInterval(A(),5);在結(jié)束話題之前,順便提一個不太常用的特性。也許你已經(jīng)注意到例子末尾的那個不起眼的 void(0), 如果你將它去掉,你會發(fā)現(xiàn)一切令人驚訝的特效都消失了,甚至連瀏覽器中的頁面也不見蹤跡,取而代之的是孤零零地顯示在瀏覽器窗口左上角的一組奇怪的數(shù)字,這是怎么回事呢? 原來 JavaScript 偽協(xié)議默認(rèn)將頁面帶到一個新的 document 中并顯示程序返回結(jié)果,所以正常情況下運(yùn)算的結(jié)果會在一個空文檔對象內(nèi)顯示

52、,這樣也就沒有圖片可以展現(xiàn)特效,而 void(0)阻止了這個跳轉(zhuǎn)動作。 void 是 JavaScript 的一個特殊的運(yùn)算符,它的作用是舍棄任何參數(shù)表達(dá)式的值,這意味著要求解析器檢驗并計算參數(shù)表達(dá)式內(nèi)容,但是卻忽略其結(jié)果。如果你刻意去檢查 void 運(yùn)算的返回值,會發(fā)現(xiàn)它返回一個 undefined 標(biāo)記(事實上任何一個不帶 return 指令的函數(shù)運(yùn)算的默認(rèn)返回值都是 undefined)。在瀏覽器的 缺省行為中,undefined 阻止了頁面的跳轉(zhuǎn)。 undefined 對于JavaScript 來說是一個特殊的值,它令我想起了某些和物理學(xué)。如果說程序中的 null 代表著“空”的話,那

53、么 undefined 則代表著“無”?!翱铡币廊皇且环N存在,而“無”則是存在的對立面。JavaScript 的一個巧妙設(shè)計就在于把“無”概念化了,由于它沒有強(qiáng)制檢驗對象存在的機(jī)制,所以它承認(rèn)“無”的概念,任何一個未經(jīng)定義和使用的標(biāo)識,均可以用“無”來表示。這個“無”在 JavaScript 文法中即是 undefined。 typeof 操作符用來檢查變量的類型,如果你直接引用一個未聲明的標(biāo)識,或者聲明了一個變量卻未對 setInterval 是 JavaScript 中一個重要的系統(tǒng)函數(shù),它提供了一種定時執(zhí)行函數(shù)的方法,另一個類似的函數(shù)是 setTimeout,我們將在第 16 章里詳細(xì)地

54、討論它們。在一些稍為復(fù)雜的應(yīng)用中,setInterval 和 setTimeout 被大量用于實現(xiàn)動態(tài)效果、模擬異步執(zhí)行、實現(xiàn)和一些控制型模式,以及實現(xiàn)自定義接口。 除了命名函數(shù)之外,JavaScript 提供了缺省函數(shù)名的定義方法,在某些特定情況下,定義在函數(shù)體內(nèi) 部的 函數(shù)在執(zhí)行的過程中形成“閉包”。除此以外,JavaScript 還提供了一種 new 操作符來實例化函數(shù)對象。以上的兩個特性使得 JavaScript 同時兼有函數(shù)式和面向?qū)ο蟮奶攸c,也使得函數(shù)成為了 JavaScript 的第一型。在第 6 章、第 22 章、第 23 章我們將會分別詳細(xì)討論 JavaScript 函數(shù)的各

55、種特性和使用技巧。 除了 Document 之外,另一個有用的接口是 Window,它提供了對瀏覽器、窗口、框架、對話框以及狀態(tài)欄的訪問方法,在第三部分里,我們會用很多篇幅仔細(xì)地討論以上兩個接口。 在例 1.2 代碼中,我們用表達(dá)式 undefined;取代 void(0),也能得到相同的結(jié)果。至此,我們對例子代碼的分析就告一段落。這段代碼的經(jīng)典之處不但在于它實現(xiàn)的效果令人驚嘆,還在于它在短短的幾行指令中體現(xiàn)了客戶端 JavaScript 中大多數(shù)重要的特性,這些特性包括我們前面提到的偽協(xié)議、全局變量、文檔接口、集合對象、函數(shù)、內(nèi)置對象、元素樣式屬性、定時器以及 void()和 undefined, 除此以外還提到了代碼中沒有出現(xiàn)的閉包、函數(shù)實例化以及 typeof 操作符,這些特性幾乎構(gòu)成了客戶端JavaScript 的全部,在后面的章節(jié)中我們也將重點圍繞著這些特性展開討論,相信一段時間之后你再回頭 看這段代碼,會有更加深刻的理解和新的收獲。 1.4.2 為客戶端服務(wù)前面我們已經(jīng)不止一次地提到過客戶端瀏覽器的概念,那么一個典型的客戶端應(yīng)用究竟是怎樣的?在這一節(jié)里,我們將概括地討論 JavaScript 基于客戶端的應(yīng)用場景,簡單介紹一下

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論