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

下載本文檔

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

文檔簡(jiǎn)介

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

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

3、與 B/S 沾邊的東西,大多是行為古怪而難以駕馭的。以你的經(jīng)驗(yàn),你會(huì)發(fā)現(xiàn)實(shí)現(xiàn)同樣的交互,用B/S 來(lái)做通常會(huì)比用任何一種客戶端程序來(lái)做要困難得多。 如果你嘗試站在用戶的角度,你會(huì)發(fā)現(xiàn)為什么大多數(shù)最終用戶對(duì) B/S 模式卻是如此的青睞。至少你不必去下載和安裝一個(gè)額外的程序到你的電腦上,不必為反復(fù)執(zhí)行安裝程序而困擾,不必整天被新的升級(jí)補(bǔ)丁打斷工作,不必理會(huì)注冊(cè)表、磁盤空間和一切對(duì)普通用戶來(lái)說(shuō)有點(diǎn)頭疼的概念。如果你的工作地點(diǎn)不是 固定的辦公室,你日常工作的 PC 也不是固定的一臺(tái)或者兩臺(tái),那么,B/S 的意義對(duì)你而言或許比想象的 還要大。 總之,用戶的需求讓 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)對(duì) Ajax 技術(shù)的關(guān)注,也令 Web 領(lǐng)域內(nèi)的一個(gè)曾經(jīng)被無(wú)數(shù)人忽視的腳本語(yǔ)言JavaScript 進(jìn)入了有遠(yuǎn)見(jiàn)的開(kāi)發(fā)人員和 IT 經(jīng)理人的視線。于是在你的手邊,也多了現(xiàn)在這本教程。 1.1.2 在什么情況下用 JavaScript一路發(fā)展到今天,JavaScript 的應(yīng)用范圍已經(jīng)大大超出一般人的想象,但是,最初的 JavaScript 是作為嵌入瀏覽器的腳本語(yǔ)言而存在,而它所提供的那些用以表示 Web 瀏覽器窗口及其內(nèi)容的對(duì)象簡(jiǎn)單實(shí)用,功能強(qiáng)大,使得 Web 應(yīng)用增色不少,以至于直到今天,在大

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

21、門語(yǔ)言,它的復(fù)雜程度未必遜色于 Perl 和Python。 之所以很多人覺(jué)得 JavaScript 過(guò)于簡(jiǎn)單,是因?yàn)樗麄兇罅渴褂玫氖且恍?JavaScript 中看似簡(jiǎn)單的文法, 解決的是一些看似簡(jiǎn)單的問(wèn)題,真正復(fù)雜而又適合 JavaScript 的領(lǐng)域卻很少有人選擇 JavaScript,真正強(qiáng)大的用法很少被涉及。JavaScript 復(fù)雜的本質(zhì)被一個(gè)個(gè)簡(jiǎn)單應(yīng)用的表象所隱藏。 我曾經(jīng)給一些堅(jiān)持認(rèn)為 JavaScript 過(guò)于簡(jiǎn)單的開(kāi)發(fā)人員寫過(guò)一段小代碼,結(jié)果令他們中的大部分內(nèi)行人大驚失色,那段代碼看起來(lái)大致像下面這個(gè)樣子: 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);因?yàn)檫@段代碼而尖叫的不僅僅包括我的這些程序員朋友,事實(shí)上,更興奮的是另一些電子領(lǐng)域的朋友, 他們寫信給我反饋說(shuō),在此之前他們從來(lái)沒(méi)有見(jiàn)到過(guò)如此形式簡(jiǎn)潔而優(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);用一個(gè)小小的堆?;蛘咂渌總z,你也可以構(gòu)造出一族差分或者其他更為復(fù)雜的數(shù)字設(shè)備,而它們明顯形式相近并且結(jié)構(gòu)優(yōu)雅。 總之,不要被簡(jiǎn)單的表象所迷惑,JavaScript 的復(fù)雜度往往很大程度上取決于你的設(shè)計(jì)思路和你的使 用技巧。JavaScript 的確是一門可以被復(fù)雜使用的程序設(shè)計(jì)語(yǔ)言。 1.1.6 令人迷惑的選擇:錦上添花還是雪中送炭本節(jié)最后的這個(gè)話題在前面已經(jīng)被隱諱地提到過(guò)多次,實(shí)際上,本小節(jié)圍繞的話題依然是什么時(shí)候使用 JavaScript。一種比較的觀點(diǎn)是在必須的時(shí)候采用,也就是前面所說(shuō)的不得不用的場(chǎng)合,另一種比這是本書中出現(xiàn)的第

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

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

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

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

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

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

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

31、務(wù)器端的 JavaScript相信大多數(shù)人對(duì)客戶端執(zhí)行的 JavaScript 并不陌生,而服務(wù)器端的 JavaScript 就鮮有人知了。不少應(yīng)用服務(wù)器提供了對(duì) 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)行。在較早一些的時(shí)候,Microsoft 已經(jīng)在 Windows 系統(tǒng)中支持一種 HTA 應(yīng)用,這可以看作是由 JavaSc

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

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

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

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

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

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

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

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

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

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

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

43、問(wèn), JavaScript 在 Web 應(yīng)用領(lǐng)域受到的好評(píng),既源于它自身靈活的動(dòng)態(tài)特性,也源于瀏覽器對(duì)它充分的支持。 下面的這段代碼在網(wǎng)絡(luò)上廣為流傳,被眾多 JavaScript 愛(ài)好者奉為代表 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);打開(kāi)一個(gè)帶有幾張圖片的網(wǎng)頁(yè)(圖片稍微多一些并且每張圖片大小相當(dāng)?shù)脑?,效果?huì)比較好),將上面這段代碼輸入到 IE 瀏覽器的地址欄(不要換行),敲回車,就會(huì)看到頁(yè)面上的所有圖片圍成一圈繞著一個(gè)點(diǎn)旋轉(zhuǎn)。事實(shí)上,這是一段有些故弄玄虛的指令,很容易讓初學(xué)者覺(jué)得新奇和迷惑,而對(duì)于資深的JavaScript 程序員來(lái)說(shuō),它幾乎恰如其分地

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

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

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

48、“寵愛(ài)”的語(yǔ)言,瀏覽器為其提供了豐富的資源和廣闊的舞臺(tái)。 document.images 之外,document 提供的屬性還能夠方便地引用頁(yè)面文檔對(duì)象中的表單、鏈接和其他元素。document 接 口 還 提 供 了 一 組 更 為 標(biāo) 準(zhǔn) 的 方 法 來(lái) 創(chuàng) 建 和 訪 問(wèn) 文 檔 元 素 , 它 們 是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)為以上三個(gè)方法是 document 對(duì)象提供的最主要的 DOM 接口。關(guān)

49、于 DOM 話題我們將會(huì)在第 12另一個(gè)需要重點(diǎn)關(guān)注的特性是函數(shù)定義,function A()聲明了一個(gè)名字叫做“A”的函數(shù),其后的一對(duì)大括號(hào)內(nèi)的指令是對(duì)這個(gè)函數(shù)的定義。提供函數(shù)文法使得 JavaScript 成為一種完善的過(guò)程式語(yǔ)言。 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 的一個(gè)有用的內(nèi)置對(duì)象,它為 JavaScript 的使用者提供了一組有用的數(shù)學(xué)函數(shù),Math.cos 返回表達(dá)式的余弦值。 在這之后我們通過(guò)一個(gè)循環(huán)將數(shù)學(xué)計(jì)算的結(jié)果賦值給 document.images 集合中提供的圖片樣式屬性, 這里引用的是 style.top 和 style.left 屬性,這兩個(gè)屬性分別定義了圖片元素左上角距參照系原點(diǎn)的橫坐標(biāo)和縱坐標(biāo)的值,默認(rèn)的單位是像素點(diǎn)(關(guān)于元素的定位問(wèn)題我們將會(huì)在后續(xù)的章節(jié)中有詳細(xì)的討論),這樣我們相當(dāng)于將頁(yè)面文檔中的圖片元素抽取出來(lái),重新計(jì)算了它們的位置,并按照新的位置進(jìn)行排列。 最后,

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

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

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

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

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

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論