JavaScript權(quán)威指南(第6版)_第1頁
JavaScript權(quán)威指南(第6版)_第2頁
JavaScript權(quán)威指南(第6版)_第3頁
JavaScript權(quán)威指南(第6版)_第4頁
JavaScript權(quán)威指南(第6版)_第5頁
已閱讀5頁,還剩965頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

JavaScript權(quán)威指南(第6版)目錄\h第1章JavaScript概述\h1.1JavaScript語言核心\h1.2客戶端JavaScript\h第一部分JavaScript語言核心\h第2章詞法結(jié)構(gòu)\h第3章類型、值和變量\h第4章表達(dá)式和運(yùn)算符\h第5章語句\h第6章對(duì)象\h第7章數(shù)組\h第8章函數(shù)\h第9章類和模塊\h第10章正則表達(dá)式的模式匹配\h第11章JavaScript的子集和擴(kuò)展\h第12章服務(wù)器端JavaScript\h第二部分客戶端JavaScript\h第13章Web瀏覽器中的JavaScript\h第14章Window對(duì)象\h第15章腳本化文檔\h第16章腳本化CSS\h第17章事件處理\h第18章腳本化HTTP\h第19章jQuery類庫\h第20章客戶端存儲(chǔ)\h第21章多媒體和圖形編程\h第22章HTML5API\h第三部分JavaScript核心參考\hJavaScript核心參考\h第四部分客戶端JavaScript參考\h客戶端JavaScript參考第1章JavaScript概述JavaScript是面向Web的編程語言。絕大多數(shù)現(xiàn)代網(wǎng)站都使用了JavaScript,并且所有的現(xiàn)代Web瀏覽器——基于桌面系統(tǒng)、游戲機(jī)、平板電腦和智能手機(jī)的瀏覽器——均包含了JavaScript解釋器。這使得JavaScript能夠稱得上史上使用最廣泛的編程語言。JavaScript也是前端開發(fā)工程師必須掌握的三種技能之一:描述網(wǎng)頁內(nèi)容的HTML、描述網(wǎng)頁樣式的CSS以及描述網(wǎng)頁行為的JavaScript。本書能幫助你掌握J(rèn)avaScript這門語言。如果你有其他語言的編程經(jīng)歷,這會(huì)有助于你了解JavaScript是一門高端的、動(dòng)態(tài)的、弱類型的編程語言,非常適合面向?qū)ο蠛秃瘮?shù)式的編程風(fēng)格。JavaScript的語法源自Java,它的一等函數(shù)(first-classfunction)來自于Scheme,它的基于原型(prototype-based)的繼承來自于Self。但使用本書學(xué)習(xí)JavaScript不必去了解那些(Java/Scheme/Self)語言或熟悉那些術(shù)語。"JavaScript"這個(gè)名字經(jīng)常被誤解。除了語法看起來和Java類似之外,JavaScript和Java是完全不同的兩種編程語言。JavaScript早已超出了其“腳本語言”(scripting-language)本身的范疇,而成為一種集健壯性、高效性和通用性為一身的編程語言。最新的語言版本為嚴(yán)謹(jǐn)?shù)拇笮蛙浖_發(fā)定義了諸多新的特性。JavaScript:名字和版本JavaScript是由Web發(fā)展初期的網(wǎng)景(Netscape)公司創(chuàng)建,"JavaScript"是SunMicrosystem公司(現(xiàn)在的Oracle)的注冊商標(biāo),用來特指網(wǎng)景(現(xiàn)在的Mozilla)對(duì)這門語言的實(shí)現(xiàn)。網(wǎng)景將這門語言作為標(biāo)準(zhǔn)提交給了ECMA——?dú)W洲計(jì)算機(jī)制造協(xié)會(huì)——由于商標(biāo)上的沖突,這門語言的標(biāo)準(zhǔn)版本改了一個(gè)丑陋的名字"ECMAScript"。同樣由于商標(biāo)的沖突,微軟對(duì)這門語言的實(shí)現(xiàn)版本取了一個(gè)廣為人知的名字"Jscript"。實(shí)際上,幾乎所有人都將這門語言叫做"JavaScript"。本書也僅僅使用"ECMAScript"來指代語言標(biāo)準(zhǔn)。在最近10年間,所有的Web瀏覽器都實(shí)現(xiàn)了第3版ECMAScript標(biāo)準(zhǔn),我們也已經(jīng)不必再去考慮版本號(hào)了:語言標(biāo)準(zhǔn)已經(jīng)很穩(wěn)定了,并且被幾乎所有瀏覽器完整地實(shí)現(xiàn)了。最近,ECMAScript第5版定義了新的語言標(biāo)準(zhǔn),在撰寫本書時(shí),瀏覽器已經(jīng)開始實(shí)現(xiàn)它了。除了ECMAScript3長期保留下來的特性,本書還涵蓋了所有ECMAScript5的新特性。正如我們經(jīng)常將JavaScript簡寫成JS一樣,ECMAScript3和ECMAScript5有時(shí)也會(huì)簡寫成ES3和ES5。當(dāng)我們提到這門語言本身時(shí),通常所指的語言版本是ECMAScript3和ECMAScript5(ECMAScript4已經(jīng)開發(fā)了數(shù)年,但由于太過龐大,從未發(fā)布過正式版本)。有時(shí)會(huì)看到JavaScript的版本號(hào)(比如JavaScript1.5或JavaScript1.8)。這些是Mozilla的版本號(hào):版本1.5基本上就是ECMAScript3,后續(xù)版本包含了非標(biāo)準(zhǔn)的語言擴(kuò)展(參照第11章)。最后,JavaScript解釋器或者“引擎”(engine)也有版本號(hào),比如,Google將它的JavaScript解釋器叫做V8,在撰寫本書時(shí)V8引擎最新版本是3.0。為了有用起見,通常每一種編程語言都有各自的開發(fā)平臺(tái)、標(biāo)準(zhǔn)庫或API函數(shù),用來提供諸如基本輸入輸出的功能。JavaScript語言核心針對(duì)文本、數(shù)組、日期和正則表達(dá)式的操作定義了很少的API,但是這些API不包括輸入輸出功能。輸入和輸出功能(類似網(wǎng)絡(luò)、存儲(chǔ)和圖形相關(guān)的復(fù)雜特性)是由JavaScript所屬的“宿主環(huán)境”(hostenviroment)提供的。這里所說的宿主環(huán)境通常是Web瀏覽器(第12章會(huì)介紹兩個(gè)不基于Web瀏覽器的JavaScript宿主環(huán)境),本書第一部分涵蓋了語言本身的特性以及少量的內(nèi)置API。第二部分講解了JavaScript如何在Web瀏覽器中工作,并涵蓋基于瀏覽器的API——這部分也稱做“客戶端JavaScript”。本書第三部分是核心API的參考手冊。比如,在這部分,可以查找"Array"以獲得JavaScript數(shù)組操作API的詳細(xì)信息。第四部分是客戶端JavaScript參考手冊,比如,你可以在這部分查找"canvas"來獲得HTML5<canvas>元素定義的圖形編程API。本書首先講解初級(jí)的基礎(chǔ)部分,然后講解更高級(jí)和更抽象的內(nèi)容。本書的章節(jié)也是如此安排以便你能循序閱讀。但學(xué)習(xí)一門新的編程語言絕非易事,當(dāng)然要完整描述這門語言就沒辦法苛求知識(shí)點(diǎn)的循次漸進(jìn),每一種語言特性都和其他特性相互關(guān)聯(lián),本書的知識(shí)點(diǎn)也是前后參照的,有時(shí)參照的知識(shí)點(diǎn)在后續(xù)章節(jié),有時(shí)在已經(jīng)閱讀的章節(jié)。本章快速介紹了語言核心部分和客戶端API及其關(guān)鍵特性,以便你能更方便更深入地閱讀理解后續(xù)章節(jié)。JavaScript初探當(dāng)學(xué)習(xí)一門新的編程語言的時(shí)候,應(yīng)當(dāng)對(duì)照書中的示例邊學(xué)邊動(dòng)手做,反復(fù)演練以加深自己的理解。因此,你需要一個(gè)JavaScript解釋器。幸運(yùn)的是,每一個(gè)Web瀏覽器都包含一個(gè)JavaScript解釋器,當(dāng)你閱讀本書時(shí),你可能已經(jīng)在電腦上安裝了不止一個(gè)Web瀏覽器了。可以通過在HTML文件里寫一個(gè)<script>標(biāo)簽來嵌入JavaScript代碼,當(dāng)瀏覽器加載HTML文件的時(shí)候,它會(huì)自動(dòng)執(zhí)行這段代碼,隨后會(huì)有提到。幸運(yùn)的是,如果運(yùn)行的是一小段JavaScript代碼,則不必每次都這樣做。我們可以利用Firefox的一個(gè)強(qiáng)大的革命性的插件Firebug(見圖1-1,可以從/下載Firebug)來運(yùn)行這些小段代碼,而且如今的Web瀏覽器帶有很多開發(fā)工具,可以用來調(diào)試、試驗(yàn)和學(xué)習(xí)。通常在瀏覽器的“工具”菜單中可以看到類似“開發(fā)者工具”或者“Web控制臺(tái)”的選項(xiàng)(Firefox4內(nèi)置了“Web控制臺(tái)”,不過更推薦使用Firebug)。可以通過按F12鍵或者Ctrl+Shift+J快捷鍵來喚醒控制臺(tái)\h[1]??刂婆_(tái)工具通常會(huì)在瀏覽器窗口的頂部或底部,有時(shí)候也可以單獨(dú)打開一個(gè)窗口(見圖1-1),這樣會(huì)更加方便。通?!伴_發(fā)者工具面板”窗口包含了很多選項(xiàng)卡,可以查看HTML文檔結(jié)構(gòu)、CSS樣式、網(wǎng)絡(luò)請(qǐng)求等。其中第一個(gè)選項(xiàng)卡是“JavaScript控制臺(tái)”,可以直接輸入JavaScript代碼并運(yùn)行出結(jié)果。用這種方式來調(diào)試JavaScript既簡單又實(shí)用,這里強(qiáng)烈推薦讀者使用這種方式來輔助你閱讀本書。一些現(xiàn)代瀏覽器有可能實(shí)現(xiàn)了一個(gè)簡單的控制臺(tái)API。可以通過使用函數(shù)console.log()來向控制臺(tái)輸出消息,使用console.log()來做簡單的輸出演示,通過這種方式可以非常方便地調(diào)試本書的示例代碼。同樣,也可以通過給alert()函數(shù)傳入一段文本來彈出一個(gè)對(duì)話框,但這種輸出調(diào)試信息的方法更具侵入性。圖1-1Firebug控制臺(tái)1.1JavaScript語言核心本節(jié)是JavaScript語言的一個(gè)快速概覽,也是本書第一部分的快速概覽。在本章之后,我們將著重關(guān)注JavaScript的基礎(chǔ)知識(shí):第2章講解JavaScript注釋、分號(hào)和Unicode字符集;第3章會(huì)更加有意思,主要講解JavaScript變量和賦值。這里有一些示例代碼來說明這兩章的重點(diǎn)內(nèi)容://所有在雙斜線之后的內(nèi)容都屬于注釋//仔細(xì)閱讀這里的注釋:它們對(duì)JavaScript代碼做了解釋//變量是表示值的一個(gè)符號(hào)名字//變量是通過var關(guān)鍵字聲明的varx;//聲明一個(gè)變量x//值可以通過等號(hào)賦值給變量x=0;//現(xiàn)在變量x的值為0x//=>0:通過變量獲取其值//JavaScript支持多種數(shù)據(jù)類型x=1;//數(shù)字x=0.01;//整數(shù)和實(shí)數(shù)共用一種數(shù)據(jù)類型x="helloworld";//由雙引號(hào)內(nèi)的文本構(gòu)成的字符串x='JavaScript';//單引號(hào)內(nèi)的文本同樣構(gòu)成字符串x=true;//布爾值x=false;//另一個(gè)布爾值x=null;//null是一個(gè)特殊的值,意思是"空"x=undefined;//undefined和null非常類似JavaScript中兩個(gè)非常重要的數(shù)據(jù)類型是對(duì)象和數(shù)組。第6章介紹對(duì)象,第7章介紹數(shù)組,對(duì)象和數(shù)組在JavaScript中是如此之重要,以至于你在本書中處處都能看到它們的身影。//JavaScript中的最重要的類型就是對(duì)象//對(duì)象是名/值對(duì)的集合,或字符串到值映射的集合varbook={//對(duì)象是由花括號(hào)括起來的topic:"JavaScript",//屬性"topic"的值是"JavaScript"fat:true//屬性"fat"的值是true};//右花括號(hào)標(biāo)記了對(duì)象的結(jié)束//通過"."或"[]"來訪問對(duì)象屬性book.topic//=>"JavaScript"book["fat"]//=>true:另外一種獲取屬性的方式book.author="Flanagan";//通過賦值創(chuàng)建一個(gè)新屬性book.contents={};//{}是一個(gè)空對(duì)象,它沒有屬性//JavaScript同樣支持?jǐn)?shù)組(以數(shù)字為索引的列表)varprimes=[2,3,5,7];//擁有4個(gè)值的數(shù)組,由"["和"]"劃定邊界primes[0]//=>2:數(shù)組中的第一個(gè)元素(索引為0)primes.length//=>4:數(shù)組中的元素個(gè)數(shù)primes[primes.length-1]//=>7:數(shù)組的最后一個(gè)元素primes[4]=9;//通過賦值來添加新元素primes[4]=11;//或通過賦值來改變已有的元素varempty=[];//[]是空數(shù)組,它具有0個(gè)元素empty.length//=>0//數(shù)組和對(duì)象中都可以包含另一個(gè)數(shù)組或?qū)ο?varpoints=[//具有兩個(gè)元素的數(shù)組{x:0,y:0},//每個(gè)元素都是一個(gè)對(duì)象{x:1,y:1}];vardata={//一個(gè)包含兩個(gè)屬性的對(duì)象trial1:[[1,2],[3,4]],//每一個(gè)屬性都是數(shù)組trial2:[[2,3],[4,5]]//數(shù)組的元素也是數(shù)組};上段代碼中通過方括號(hào)定義數(shù)組元素和通過花括號(hào)定義對(duì)象屬性名和屬性值之間的映射關(guān)系的語法稱為初始化表達(dá)式(initializerexpression),第4章有專門的介紹。表達(dá)式是JavaScript中的一個(gè)短語,這個(gè)短語可以通過運(yùn)算得出一個(gè)值。通過“.”和“[]”來引用對(duì)象屬性或數(shù)組元素的值就構(gòu)成一個(gè)表達(dá)式。比如,請(qǐng)看一下上述代碼中獨(dú)占一行的表達(dá)式,其后的注釋中箭頭(=>)后的值就是表達(dá)式的運(yùn)算結(jié)果。這種寫法是本書中的一種約定表述方式。JavaScript中最常見的表達(dá)式寫法是像下面代碼這樣使用運(yùn)算符(operator)://運(yùn)算符作用于操作數(shù),生成一個(gè)新的值//最常見的是算術(shù)運(yùn)算符3+2//=>5:加法3-2//=>1:減法3*2//=>6:乘法3/2//=>1.5:除法points[1].x-points[0].x//=>1:更復(fù)雜的操作數(shù)也能照常工作"3"+"2"http://=>"32":+可以完成加法運(yùn)算也可以作字符串連接//JavaScript定義了一些算術(shù)運(yùn)算符的簡寫形式varcount=0;//定義一個(gè)變量count++;//自增1count--;//自減1count+=2;//自增2:和"count=count+2;"寫法一樣count*=3;//自乘3:和"count=count*3;"寫法一樣count//=>6:變量名本身也是一個(gè)表達(dá)式//相等關(guān)系運(yùn)算符用來判斷兩值是否相等//不等、大于、小于運(yùn)算符的運(yùn)算結(jié)果是true或falsevarx=2,y=3;//這里的=等號(hào)是賦值的意思,不是比較相等x==y//=>false:相等x!=y//=>true:不等x<y//=>true:小于x<=y//=>true:小于等于x>y//=>false:大于等于x>=y//=>false:大于等于"two"=="three"http://=>false:兩個(gè)字符串不相等"two">"three"http://=>true:"tw"在字母表中的索引大于"th"false==(x>y)//=>true:false和false相等//邏輯運(yùn)算符是對(duì)布爾值的合并或求反(x==2)&&(y==3)//=>true:兩個(gè)比較都是true,&&表示"與"(x>3)||(y<3)//=>false:兩個(gè)比較不都是true,||表示"或"!(x==y)//=>true:!求反如果JavaScript中的“短語”是表達(dá)式的話,那么整個(gè)句子就稱做語句(statement),第5章會(huì)詳細(xì)講解。在上述代碼中,以分號(hào)結(jié)束的行均是一條語句(下面的代碼中,會(huì)看到省略分號(hào)的多行語句)。實(shí)際上,語句和表達(dá)式之間有很多共同之處,粗略地講,表達(dá)式僅僅計(jì)算出一個(gè)值但并不作任何操作,它并不改變程序的運(yùn)行狀態(tài)。而語句并不包含一個(gè)值(或者說它包含的值我們并不關(guān)心),但它們改變程序的運(yùn)行狀態(tài)。在上文中已經(jīng)見過變量聲明語句和賦值語句。另一類語句是“控制結(jié)構(gòu)”(controlstructure),比如條件判斷和循環(huán)。在介紹完函數(shù)之后,我們給出相關(guān)的示例代碼。函數(shù)是帶有名稱(named)\h[2]和參數(shù)的JavaScript代碼段,可以一次定義多次調(diào)用。第8章會(huì)正式詳細(xì)地講解函數(shù)。與對(duì)象和數(shù)組一樣,在本書的很多地方都會(huì)提到函數(shù)。這里是一些簡單的示例代碼://函數(shù)是一段帶有參數(shù)的JavaScript代碼端,可以多次調(diào)用functionplus1(x){//定義了名為plus1的一個(gè)函數(shù),帶有參數(shù)xreturnx+1;//返回一個(gè)比傳入的參數(shù)大的值}//函數(shù)的代碼塊是由花括號(hào)包裹起來的部分plus1(y)//=>4:y為3,調(diào)用函數(shù)的結(jié)果為3+1varsquare=function(x){//函數(shù)是一種值,可以賦值給變量returnx*x;//計(jì)算函數(shù)的值};//分號(hào)標(biāo)識(shí)了賦值語句的結(jié)束square(plus1(y))//=>16:在一個(gè)表達(dá)式中調(diào)用兩個(gè)函數(shù)當(dāng)將函數(shù)和對(duì)象合寫在一起時(shí),函數(shù)就變成了“方法”(method)://當(dāng)函數(shù)賦值給對(duì)象的屬性,我們稱為//"方法",所有的JavaScript對(duì)象都含有方法vara=[];//創(chuàng)建一個(gè)空數(shù)組a.push(1,2,3);//push()方法向數(shù)組中添加元素a.reverse();//另一個(gè)方法:將數(shù)組元素的次序反轉(zhuǎn)//我們也可以定義自己的方法,"this"關(guān)鍵字是對(duì)定義方法//的對(duì)象的引用:這里的例子是上文中提到的包含兩個(gè)點(diǎn)位置信息的數(shù)組points.dist=function(){//定義一個(gè)方法用來計(jì)算兩點(diǎn)之間的距離varp1=this[0];//通過this獲得對(duì)當(dāng)前數(shù)組的引用varp2=this[1];//并取得調(diào)用的數(shù)組前兩個(gè)元素vara=p2.x-p1.x;//X坐標(biāo)軸上的距離varb=p2.y-p1.y;//Y坐標(biāo)軸上的距離returnMath.sqrt(a*a+//勾股定理我們稱為b*b);//用Math.sqrt()來計(jì)算平方根};points.dist()//=>1.414:求得兩個(gè)點(diǎn)之間的距離現(xiàn)在,給出一些控制語句的例子,這里的示例函數(shù)體內(nèi)包含了最常見的JavaScript控制語句://這些JavaScript語句使用該語法包含條件判斷和循環(huán)//使用了類似C、C++、Java和其他語言的語法functionabs(x){//求絕對(duì)值的函數(shù)if(x>=0){//if語句...returnx;//如果比較結(jié)果為true則執(zhí)行這里的代碼.}//子句的結(jié)束.else{//當(dāng)if條件不滿足時(shí)執(zhí)行else子句return-x;}//如果分支中只有一條語句,花括號(hào)是可以省略的}//注意if/else中嵌套的return語句functionfactorial(n){//計(jì)算階乘的函數(shù)varproduct=1;//給product賦值為1while(n>1){//當(dāng)()內(nèi)的表達(dá)式為true時(shí)循環(huán)執(zhí)行{}內(nèi)的代碼product*=n;//"product=product*n;"的簡寫形式n--;//"n=n-1;"的簡寫形式}//循環(huán)結(jié)束returnproduct;//返回product}factorial(4)//=>24:1*4*3*2functionfactorial2(n){//實(shí)現(xiàn)循環(huán)的另一種寫法vari,product=1;//給product賦值為1for(i=2;i<=n;i++)//將i從2自增至nproduct*=i;//循環(huán)體,當(dāng)循環(huán)體中只有一句代碼,可以省略{}returnproduct;//返回計(jì)算好的階乘}factorial2(5)//=>120:1*2*3*4*5JavaScript是一種面向?qū)ο蟮木幊陶Z言,但和傳統(tǒng)的面向?qū)ο笥钟泻艽髤^(qū)別。第9章將詳細(xì)講解JavaScript中的面向?qū)ο缶幊?,這一章有大量的示例代碼,是本書中最長的一章。這里有一個(gè)簡單的示例,這段代碼展示了如何在JavaScript中定義一個(gè)類來表示2D平面幾何中的點(diǎn)。這個(gè)類實(shí)例化的對(duì)象擁有一個(gè)名為r()的方法,用來計(jì)算該點(diǎn)到原點(diǎn)的距離://定義一個(gè)構(gòu)造函數(shù)以初始化一個(gè)新的Point對(duì)象functionPoint(x,y){//按照慣例,構(gòu)造函數(shù)均以大寫字母開始this.x=x;//關(guān)鍵字this指代初始化的實(shí)例this.y=y;//將函數(shù)參數(shù)存儲(chǔ)為對(duì)象的屬性}//不需要return//使用new關(guān)鍵字和構(gòu)造函數(shù)來創(chuàng)建一個(gè)實(shí)例varp=newPoint(1,1);//平面幾何中的點(diǎn)(1,1)//通過給構(gòu)造函數(shù)的prototye對(duì)象賦值//來給Point對(duì)象定義方法Ptotype.r=function(){2returnMath.sqrt(//返回x+y2的平方根this.x*this.x+//this指代調(diào)用這個(gè)方法的對(duì)象this.y*this.y);};//Point的實(shí)例對(duì)象p(以及所有的Point實(shí)例對(duì)象)繼承了方法r()p.r()//=>1.414...第9章是第一部分的精華所在,后續(xù)的各章做了一些零星的延伸,將我們對(duì)JavaScript語言核心的探索帶向尾聲。第10章主要講解了正則表達(dá)式的語法,并演示了如何使用這些“正則表達(dá)式”進(jìn)行文本的模式匹配。第11章介紹JavaScript語言核心的子集和超集。最后,在進(jìn)入客戶端JavaScript的內(nèi)容之前,第12章介紹兩種在Web瀏覽器之外的兩種JavaScirpt運(yùn)行環(huán)境。\h[1]F12用來喚醒/關(guān)閉Firebug操作面板,Ctrl+Shift+J用來喚醒錯(cuò)誤控制臺(tái)(ErrorConsole)。\h[2]這里“名稱”含義是指函數(shù)具有固定標(biāo)識(shí),并不是指函數(shù)變量名稱。1.2客戶端JavaScriptJavaScript語言核心部分的內(nèi)容中的知識(shí)點(diǎn)交叉引用比較多,且知識(shí)點(diǎn)的層次感并不分明。而在客戶端JavaScript部分的內(nèi)容編排方式有了較大改變。依照本書給定的知識(shí)點(diǎn)順序進(jìn)行學(xué)習(xí),完全可以學(xué)會(huì)如何在Web瀏覽器中使用JavaScript。但如果你想通過閱讀本書來學(xué)習(xí)客戶端JavaScript的話,不能只將眼光落在第二部分,所以本節(jié)會(huì)對(duì)于客戶端編程技術(shù)做一個(gè)快速概覽,隨后會(huì)給出一個(gè)有深度的示例。第13章是第二部分的第一章,該章介紹如何讓JavaScript在Web瀏覽器中運(yùn)行起來。從該章學(xué)到的最重要的內(nèi)容是,JavaScript代碼可以通過<scirpt>標(biāo)簽來嵌入到HTML文件中:<html><head><scriptsrc="library.js"></script><!--引入一個(gè)JavaScript庫--></head><body><p>ThisisaparagraphofHTML</p><script>//在這里編寫嵌入到HTML文件中的JavaScript代碼</script><p>HereismoreHTML</P></body></html>第14章講解Web瀏覽器端腳本技術(shù),并涵蓋客戶端JavaScript中的一些重要全局函數(shù),例如:<script>functionmoveon(){//通過彈出一個(gè)對(duì)話框來詢問用戶一個(gè)問題varanswer=confirm("準(zhǔn)備好了嗎?");//單擊"確定"按鈕,瀏覽器會(huì)加載一個(gè)新頁面if(answer)window.location="";}//在1分鐘(6萬毫秒)后執(zhí)行定義的這個(gè)函數(shù)setTimeout(moveon,60000);</script>我們注意到,本節(jié)展示的客戶端示例代碼要比前面的示例代碼要長很多。這里的示例代碼并不是用來在Firebug(或者其他調(diào)試工具)控制臺(tái)窗口中直接輸入的,而是作為一個(gè)單獨(dú)的HTML文件,并在Web瀏覽器中直接打開運(yùn)行的。比如,上述代碼段就是一個(gè)HTML文件的完整內(nèi)容。第15章的內(nèi)容更加務(wù)實(shí)——通過腳本來操縱HTML文檔內(nèi)容。它將展示如何選取特定的HTML元素、如何給HTML元素設(shè)置屬性、如何修改元素內(nèi)容,以及如何給文檔添加新節(jié)點(diǎn)。這里的示例函數(shù)展示了如何查找和修改基本文檔的內(nèi)容://在document中的一個(gè)指定的區(qū)域輸出調(diào)試消息//如果document不存在這樣一個(gè)區(qū)域,則創(chuàng)建一個(gè)functiondebug(msg){//通過查看HTML元素id屬性來查找文檔的調(diào)試部分varlog=document.getElementById("debuglog");//如果這個(gè)元素不存在,則創(chuàng)建一個(gè)if(!log){log=document.createElement("div");//創(chuàng)建一個(gè)新的<div>元素log.id="debuglog";//給這個(gè)元素的HTMLid賦值log.innerHTML="<h1>DebugLog</h1>";//定義初始內(nèi)容document.body.appendChild(log);//將其添加到文檔的末尾}//將消息包裝在<pre>中,并添加至log中varpre=document.createElement("pre");//創(chuàng)建<pre>標(biāo)簽vartext=document.createTextNode(msg);//將msg包裝在一個(gè)文本節(jié)點(diǎn)中pre.appendChild(text);//將文本添加至<pre>log.appendChild(pre);//將<pre>添加至log}第15章講述JavaScript如何操縱HTML中定義Web內(nèi)容的元素。第16章講述如何使用JavaScript來進(jìn)行CSS樣式操作,CSS樣式定義了內(nèi)容的展示方式。這通常會(huì)使用到HTML元素的style和class屬性:functionhide(e,reflow){//通過JavaScript操縱樣式來隱藏元素eif(reflow){//如果第二個(gè)參數(shù)是truee.style.display="none"http://隱藏這個(gè)元素,其所占的空間也隨之消失}else{//否則e.style.visibility="hidden";//將e隱藏,但是保留其所占的空間}}functionhighlight(e){//通過設(shè)置CSS類來高亮顯示e//簡單地定義或追加HTML類屬性//這里假設(shè)CSS樣式表中已經(jīng)有"hilite"類的定義if(!e.className)e.className="hilite";elsee.className+="hilite";}可以通過JavaScript來操控Web瀏覽器中的HTML內(nèi)容和文檔的CSS樣式,同樣,也可以通過事件處理程序(eventhandler)來定義文檔的行為。事件處理程序是一個(gè)在瀏覽器中注冊的JavaScript函數(shù),當(dāng)特定類型的事件發(fā)生時(shí)瀏覽器便調(diào)用這個(gè)函數(shù)。通常我們關(guān)心的事件類型是鼠標(biāo)點(diǎn)擊事件和鍵盤按鍵事件(在智能手機(jī)中則是各種觸碰事件)。或者說,當(dāng)瀏覽器完成了文檔的加載,當(dāng)用戶改變窗口大小或當(dāng)用戶向HTML表單元素中輸入數(shù)據(jù)時(shí)便會(huì)觸發(fā)一個(gè)事件。第17章詳細(xì)描述如何定義、注冊事件處理程序,以及在事件發(fā)生時(shí)瀏覽器是如何調(diào)用它們的。定義事件處理程序最簡單的方法是,給HTML的以"on"為前綴的屬性綁定一個(gè)回調(diào)。當(dāng)寫一些簡單的測試程序時(shí),最實(shí)用的方法就是給"onclick"處理程序綁定回調(diào)。假定已經(jīng)將上文中的debug()和hide()兩個(gè)函數(shù)保存至名為debug.js和hide.js的文件中,那么就可以寫一個(gè)簡單的HTML測試文件,來給<button>元素的onclick屬性指定一個(gè)事件處理程序:<scriptsrc="debug.js"></script><scriptsrc="hide.js"></script>Hello<buttononclick="hide(this,true);debug('hidebutton1');">Hide1</button><buttononclick="hide(this);debug('hidebutton2');">Hide2</button>W(wǎng)orld下面這些客戶端JavaScript代碼用到了事件,它給一個(gè)很重要的事件——"load"事件注冊了一個(gè)事件處理程序。同時(shí),也展示了注冊"click"事件處理函數(shù)更高級(jí)的一種方法://"load"事件只有在文檔加載完成后才會(huì)觸發(fā)//通常需要等待load事件發(fā)生后才開始執(zhí)行JavaScript代碼window.onload=function(){//當(dāng)文檔加載完成時(shí)執(zhí)行這里的代碼//找到文檔中所有的<img>標(biāo)簽varimages=document.getElementsByTagName("img");//遍歷images,給每個(gè)節(jié)點(diǎn)的"click"事件添加事件處理程序//在點(diǎn)擊圖片的時(shí)候?qū)D片隱藏for(vari=0;i<images.length;i++){varimage=images[i];if(image.addEventListener)//注冊事件處理程序的另一種方法image.addEventListener("click",hide,false);else//兼容IE8及以前的版本image.attachEvent("onclick",hide);}//這便是上面注冊的事件處理函數(shù)functionhide(event){event.target.style.visibility="hidden";}};第15~17章講述了如何使用JavaScript來操控網(wǎng)頁的內(nèi)容(HTML)、樣式(CSS)以及行為(事件處理)。這些章所討論的API多少有些復(fù)雜,且至今仍具有糟糕的瀏覽器兼容性。也正是由于這個(gè)原因,很多客戶端JavaScript程序員選擇使用“庫”或“框架”來簡化他們的編碼工作。最流行的庫非jQuery莫屬。第19章將會(huì)詳細(xì)介紹jQuery庫。jQuery定義了一套靈巧易用的API,用來操控文檔內(nèi)容、樣式和行為。jQuery經(jīng)過了完整的測試,在所有現(xiàn)代主流瀏覽器,甚至在IE6這種早期瀏覽器中都可以照常運(yùn)行。jQuery代碼非常易于識(shí)別,因?yàn)樗浞掷昧艘粋€(gè)名為$()的函數(shù)。這里用jQuery重寫了上文中提到的debug()函數(shù):functiondebug(msg){varlog=$("#debuglog");//找到要顯示msg的元素.if(log.length==0){//如果不存在則創(chuàng)建之log=$("<divid='debuglog'><h1>DebugLog</h1></div>");log.appendTo(document.body);//并將其追加到body里}log.append($("<pre/>").text(msg));//將msg包裝在<pre>中,再追加到log里}目前我們所提到的第二部分的4章都是圍繞網(wǎng)頁展開討論的。后續(xù)的4章將著眼點(diǎn)轉(zhuǎn)向Web應(yīng)用。這幾章的內(nèi)容并不是討論如何通過編寫操控內(nèi)容、樣式和行為的腳本使用Web瀏覽器來渲染文檔;而是講解如何將Web瀏覽器當(dāng)做應(yīng)用平臺(tái),并描述了用以支持更復(fù)雜精細(xì)的客戶端Web應(yīng)用的現(xiàn)代瀏覽器API。第18章講解如何使用JavaScript來發(fā)起HTTP請(qǐng)求。第20章描述數(shù)據(jù)存儲(chǔ)的機(jī)制以及客戶端應(yīng)用中的會(huì)話狀態(tài)的保持。第21章涵蓋基于HTML的<vanvas>標(biāo)簽的客戶端API,用來進(jìn)行任意形狀圖形的繪制。最后,第22章講解HTML5所提供的新一代Web應(yīng)用API。網(wǎng)絡(luò)、存儲(chǔ)、圖形:這些都是Web瀏覽器提供的操作系統(tǒng)級(jí)的服務(wù),它們定義了全新的跨平臺(tái)的應(yīng)用環(huán)境。如果你正在進(jìn)行基于那些支持這些新API的瀏覽器的開發(fā),這將是你作為客戶端JavaScript程序員最激動(dòng)人心的時(shí)刻。最后4章并沒有太多示例代碼,但下面的例子使用了這些新的API。示例:一個(gè)JavaScript貸款計(jì)算器本章最后展示一個(gè)例子,這個(gè)例子集中使用了諸多技術(shù),展示了真實(shí)環(huán)境下的客戶端JavaScript(包括HTML和CSS)編程。例1-1給出了一個(gè)簡單的貸款計(jì)算器應(yīng)用的代碼,如圖1-2所示。圖1-2一個(gè)貸款計(jì)算器Web應(yīng)用在看代碼(例1-1)之前應(yīng)當(dāng)先仔細(xì)閱讀本段文字。你不需要理解所有內(nèi)容,代碼中有著完整的注釋,至少你應(yīng)該能正確運(yùn)行這段代碼得到如圖1-2所示的界面。這里的例子展示了諸多JavaScript語言核心特性,同樣展示了重要的客戶端JavaScript技術(shù):·如何在文檔中查找元素·如何通過表單input元素來獲取用戶的輸入數(shù)據(jù)·如何通過文檔元素來設(shè)置HTML內(nèi)容·如何將數(shù)據(jù)存儲(chǔ)在瀏覽器中·如何使用腳本發(fā)起HTTP請(qǐng)求·如何利用<canvas>元素繪圖例1-1:基于JavaScript實(shí)現(xiàn)的貸款計(jì)算器<!DOCTYPEhtml><html><head><title>JavaScriptLoanCalculator</title><style>/*這是一個(gè)CSS樣式表:定義了程序輸出的樣式*/.output{font-weight:bold;}/*計(jì)算結(jié)果定義為粗體*/#payment{text-decoration:underline;}/*定義id="payment"的元素樣式*/#graph{border:solidblack1px;}/*圖表有一個(gè)1像素的邊框*/th,td{vertical-align:top;}/*表格單元格對(duì)其方式為頂端對(duì)齊*/</style></head><body><!--這是一個(gè)HTML表格,其中包含<input>元素可以用來輸入數(shù)據(jù)。程序?qū)⒃冢約pan>元素中顯示計(jì)算結(jié)果,這些元素都具有類似"interset"和"years"的id這些id將在表格下面的JavaScript代碼中用到。我們注意到,有一些input元素定義了"onchange"或"onclick"的事件處理程序,以便用戶在輸入數(shù)據(jù)或者點(diǎn)擊inputs時(shí)執(zhí)行指定的JavaScript代碼段--><table><tr><th>EnterLoanData:</th><td></td><th>LoanBalance,CumulativeEquity,andInterestPayments</th></tr><tr><td>Amountoftheloan($):</td><td><inputid="amount"onchange="calculate();"></td><tdrowspan=8><canvasid="graph"width="400"height="250"></canvas></td></tr><tr><td>Annualinterest(%):</td><td><inputid="apr"onchange="calculate();"></td></tr><tr><td>Repaymentperiod(years):</td><td><inputid="years"onchange="calculate();"></td><tr><td>Zipcode(tofindlenders):</td><td><inputid="zipcode"onchange="calculate();"></td><tr><th>ApproximatePayments:</th><td><buttononclick="calculate();">Calculate</button></td></tr><tr><td>Monthlypayment:</td><td>$<spanclass="output"id="payment"></span></td></tr><tr><td>Totalpayment:</td><td>$<spanclass="output"id="total"></span></td></tr><tr><td>Totalinterest:</td><td>$<spanclass="output"id="totalinterest"></span></td></tr><tr><th>Sponsors:</th><tdcolspan=2>Applyforyourloanwithoneofthesefinelenders:<divid="lenders"></div></td></tr></table><!--隨后是JavaScirpt代碼,這些代碼內(nèi)嵌在了一個(gè)<script>標(biāo)簽里--><!--通常情況下,這些腳本代碼應(yīng)當(dāng)放在<head>標(biāo)簽中--><!--將JavaScript代碼放在HTML代碼之后僅僅是為了便于理解--><script>"usestrict";//如果瀏覽器支持的話,則開啟ECMAScript5的嚴(yán)格模式/**這里的腳本定義了caculate()函數(shù),在HTML代碼中綁定事件處理程序時(shí)會(huì)調(diào)用它*這個(gè)函數(shù)從<input>元素中讀取數(shù)據(jù),計(jì)算貸款賠付信息,并將結(jié)果顯示在<span>元素中*同樣,這里還保存了用戶數(shù)據(jù)、展示了放貸人鏈接并繪制出了圖表*/functioncalculate(){//查找文檔中用于輸入輸出的元素varamount=document.getElementById("amount");varapr=document.getElementById("apr");varyears=document.getElementById("years");varzipcode=document.getElementById("zipcode");varpayment=document.getElementById("payment");vartotal=document.getElementById("total");vartotalinterest=document.getElementById("totalinterest");//假設(shè)所有的輸入都是合法的,將從input元素中獲取輸入數(shù)據(jù)//將百分比格式轉(zhuǎn)換為小數(shù)格式,并從年利率轉(zhuǎn)換為月利率//將年度賠付轉(zhuǎn)換為月度賠付varprincipal=parseFloat(amount.value);varinterest=parseFloat(apr.value)/100/12;varpayments=parseFloat(years.value)*12;//現(xiàn)在計(jì)算月度賠付的數(shù)據(jù)varx=Math.pow(1+interest,payments);//Math.pow()進(jìn)行冪次運(yùn)算varmonthly=(principal*x*interest)/(x-1);//如果結(jié)果沒有超過JavaScript能表示的數(shù)字范圍,且用戶的輸入也正確//這里所展示的結(jié)果就是合法的if(isFinite(monthly)){//將數(shù)據(jù)填充至輸出字段的位置,四舍五入到小數(shù)點(diǎn)后兩位數(shù)字payment.innerHTML=monthly.toFixed(2);total.innerHTML=(monthly*payments).toFixed(2);totalinterest.innerHTML=((monthly*payments)-principal).toFixed(2);//將用戶的輸入數(shù)據(jù)保存下來,這樣在下次訪問時(shí)也能取到數(shù)據(jù)save(amount.value,apr.value,years.value,zipcode.value);//找到并展示本地放貸人,但忽略網(wǎng)絡(luò)錯(cuò)誤try{//捕獲這段代碼拋出的所有異常getLenders(amount.value,apr.value,years.value,zipcode.value);}catch(e){/*忽略這些異常*/}//最后,用圖表展示貸款余額、利息和資產(chǎn)收益chart(principal,interest,monthly,payments);}else{//計(jì)算結(jié)果不是數(shù)字或者是無窮大,意味著輸入數(shù)據(jù)是非法或不完整的//清空之前的輸出數(shù)據(jù)payment.innerHTML="";//清空元素的文本內(nèi)容total.innerHTML=""totalinterest.innerHTML="";chart();//不傳參數(shù)的話就是清除圖表}}//將用戶的輸入保存至localStorage對(duì)象的屬性中//這些屬性在再次訪問時(shí)還會(huì)繼續(xù)保持在原位置//如果你在瀏覽器中按照file://URL的方式直接打開本地文件,//則無法在某些瀏覽器中使用存儲(chǔ)功能(比如FireFox)//而通過HTTP打開文件是可行的functionsave(amount,apr,years,zipcode){if(window.localStorage){//只有在瀏覽器支持的時(shí)候才運(yùn)行這里的代碼localStorage.loan_amount=amount;localStorage.loan_apr=apr;localStorage.loan_years=years;localStorage.loan_zipcode=zipcode;}}//在文檔首次加載時(shí),將會(huì)嘗試還原輸入字段window.onload=function(){//如果瀏覽器支持本地存儲(chǔ)并且上次保存的值是存在的if(window.localStorage&&localStorage.loan_amount){document.getElementById("amount").value=localStorage.loan_amount;document.getElementById("apr").value=localStorage.loan_apr;document.getElementById("years").value=localStorage.loan_years;document.getElementById("zipcode").value=localStorage.loan_zipcode;}};//將用戶的輸入發(fā)送至服務(wù)器端腳本(理論上)將//返回一個(gè)本地放貸人的鏈接列表,在這個(gè)例子中并沒有實(shí)現(xiàn)這種查找放貸人的服務(wù)//但如果該服務(wù)存在,該函數(shù)會(huì)使用它functiongetLenders(amount,apr,years,zipcode){//如果瀏覽器不支持XMLHttpRequest對(duì)象,則退出if(!window.XMLHttpRequest)return;//找到要顯示放貸人列表的元素varad=document.getElementById("lenders");if(!ad)return;//如果返回為空,則退出//將用戶的輸入數(shù)據(jù)進(jìn)行URL編碼,并作為查詢參數(shù)附加在URL里varurl="getLenders.php"+//處理數(shù)據(jù)的URL地址"?amt="+encodeURIComponent(amount)+//使用查詢串中的數(shù)據(jù)"&apr="+encodeURIComponent(apr)+"&yrs="+encodeURIComponent(years)+"&zip="+encodeURIComponent(zipcode);//通過XMLHttpRequest對(duì)象來提取返回?cái)?shù)據(jù)varreq=newXMLHttpRequest();//發(fā)起一個(gè)新的請(qǐng)求req.open("GET",url);//通過URL發(fā)起一個(gè)HTTPGET請(qǐng)求req.send(null);//不帶任何正文發(fā)送這個(gè)請(qǐng)求//在返回?cái)?shù)據(jù)之前,注冊了一個(gè)事件處理函數(shù),這個(gè)處理函數(shù)//將會(huì)在服務(wù)器的響應(yīng)返回至客戶端的時(shí)候調(diào)用//這種異步編程模型在客戶端JavaScript中是非常常見的req.onreadystatechange=function(){if(req.readyState==4&&req.status==200){//如果代碼運(yùn)行到這里,說明我們得到了一個(gè)合法且完整的HTTP響應(yīng)varresponse=req.responseText;//HTTP響應(yīng)是以字符串的形式呈現(xiàn)的varlenders=JSON.parse(response);//將其解析為JS數(shù)組//將數(shù)組中的放貸人對(duì)象轉(zhuǎn)換為HTML字符串形式varlist="";for(vari=0;i<lenders.length;i++){list+="<li><ahref='"+lenders[i].url+"'>"+lenders[i].name+"</a>";}//將數(shù)據(jù)在HTML元素中呈現(xiàn)出來ad.innerHTML="<ul>"+list+"</ul>";}}}//在HTML<canvas>元素中用圖表展示月度貸款余額、利息和資產(chǎn)收益//如果不傳入?yún)?shù)的話,則清空之前的圖表數(shù)據(jù)functionchart(principal,interest,monthly,payments){vargraph=document.getElementById("graph");//得到<canvas>標(biāo)簽graph.width=graph.width;//用一種巧妙的手法清除并重置畫布//如果不傳入?yún)?shù),或者瀏覽器不支持畫布,則直接返回if(arguments.length==0||!graph.getContext)return;//獲得畫布元素的"context"對(duì)象,這個(gè)對(duì)象定義了一組繪畫APIvarg=graph.getContext("2d");//所有的繪畫操作都將基于這個(gè)對(duì)象varwidth=graph.width,height=graph.height;//獲得畫布大小//這里的函數(shù)作用是將付款數(shù)字和美元數(shù)據(jù)轉(zhuǎn)換為像素functionpaymentToX(n){returnn*width/payments;}functionamountToY(a){returnheight-(a*height/(monthly*payments*1.05));}//付款數(shù)據(jù)是一條從(0,0)到(payments,monthly*payments)的直線g.moveTo(paymentToX(0),amountToY(0));//從左下方開始g.lineTo(paymentToX(payments),//繪至右上方amountToY(monthly*payments));g.lineTo(paymentToX(payments),amountToY(0));//再至右下方g.closePath();//將結(jié)尾連接至開頭g.fillStyle="#f88";//亮紅色g.fill();//填充矩形g.font="bold12pxsans-serif";//定義一種字體g.fillText("TotalInterestPayments",20,20);//將文字繪制到圖例中//很多資產(chǎn)數(shù)據(jù)并不是線性的,很難將其反映至圖表中varequity=0;g.beginPath();//開始繪制新圖形g.moveTo(paymentToX(0),amountToY(0));//從左下方開始for(varp=1;p<=payments;p++){//計(jì)算出每一筆賠付的利息varthisMonthsInterest=(principal-equity)*interest;equity+=(monthly-thisMonthsInterest);//得到資產(chǎn)額g.lineTo(paymentToX(p),amountToY(equity));//將數(shù)據(jù)繪制到畫布上}g.lineTo(paymentToX(payments),amountToY(0));//將數(shù)據(jù)線繪制至x軸g.closePath();//將線條結(jié)尾連接至線條開頭g.fillStyle="green";//使用綠色繪制圖形g.fill();//曲線之下的部分均填充g.fillText("TotalEquity",20,35);//文本顏色設(shè)置為綠色//再次循環(huán),余額數(shù)據(jù)顯示為黑色粗線條varbal=principal;g.beginPath();g.moveTo(paymentToX(0),amountToY(bal));for(varp=1;p<=payments;p++){varthisMonthsInterest=bal*interest;bal-=(monthly-thisMonthsInterest);//得到資產(chǎn)額g.lineTo(paymentToX(p),amountToY(bal));//將直線連接至某點(diǎn)}g.lineWidth=3;//將直線寬度加粗g.stroke();//繪制余額的曲線g.fillStyle="black";//使用黑色字體g.fillText("LoanBalance",20,50);//圖例文字//將年度數(shù)據(jù)在X軸做標(biāo)記g.textAlign="center";//文字居中對(duì)齊vary=amountToY(0);//Y坐標(biāo)設(shè)為0for(varyear=1;year*12<=payments;year++){//遍歷每年varx=paymentToX(year*12);//計(jì)算標(biāo)記位置g.fillRect(x-0.5,y-3,1,3);//開始繪制標(biāo)記if(year==1)g.fillText("Year",x,y-5);//在坐標(biāo)軸做標(biāo)記if(year%5==0&&year*12!==payments)//每5年的數(shù)據(jù)g.fillText(String(year),x,y-5);}//將賠付數(shù)額標(biāo)記在右邊界g.textAlign="right";//文字右對(duì)齊g.textBaseline="middle";//文字垂直居中varticks=[monthly*payments,principal];//我們將要用到的兩個(gè)點(diǎn)varrightEdge=paymentToX(payments);//設(shè)置X坐標(biāo)for(vari=0;i<ticks.length;i++){//對(duì)每兩個(gè)點(diǎn)做循環(huán)vary=amountToY(ticks[i]);//計(jì)算每個(gè)標(biāo)記的Y坐標(biāo)g.fillRect(rightEdge-3,y-0.5,3,1);//繪制標(biāo)記g.fillText(String(ticks[i].toFixed(0)),//繪制文本rightEdge-5,y);}}</script></body></html>第一部分JavaScript語言核心本書該部分(第2~12章)描述JavaScript語言核心。這部分是該語言的主要參考資料。學(xué)習(xí)之初通讀一遍該部分,以后在遇到JavaScript的難點(diǎn)時(shí),回到這里重新查閱相關(guān)內(nèi)容以鞏固知識(shí)的掌握:第2章詞法結(jié)構(gòu)第3章類型、值和變量第4章表達(dá)式和運(yùn)算符第5章語句第6章對(duì)象第7章數(shù)組第8章函數(shù)第9章類和模塊第10章正則表達(dá)式的模式匹配第11章JavaScript的子集和擴(kuò)展第12章服務(wù)器端JavaScript第2章詞法結(jié)構(gòu)編程語言的詞法結(jié)構(gòu)是一套基礎(chǔ)性規(guī)則,用來描述如何使用這門語言來編寫程序。作為語法的基礎(chǔ),它規(guī)定了諸如變量名是什么樣的、怎么寫注釋,以及程序語句之間如何分隔等規(guī)則。本章用很短的篇幅來介紹JavaScript的詞法結(jié)構(gòu)。2.1字符集JavaScript程序是用Unicode字符集編寫的。Unicode是ASCII和Latin-1的超集,并支持地球上幾乎所有在用的語言。ECMAScript3要求JavaScript的實(shí)現(xiàn)必須支持Unicode2.1及后續(xù)版本,ECMAScript5則要求支持Unicode3及后續(xù)版本??梢詤⒖?.2節(jié)的“邊欄”來了解更多關(guān)于Unicode和JavaScript的信息。2.1.1區(qū)分大小寫JavaScript是區(qū)分大小寫的語言。也就是說,關(guān)鍵字、變量、函數(shù)名和所有的標(biāo)識(shí)符(identifier)都必須采取一致的大小寫形式。比如,關(guān)鍵字"while"必須寫成"while",而不能寫成"While"或者"WHILE"。同樣,"online"、"Online"、"OnLine"和"ONLINE"是4個(gè)不同的變量名。但需要注意的是,HTML并不區(qū)分大小寫(盡管XHTML區(qū)分大小寫)。由于它和客戶端JavaScript聯(lián)系緊密,因此這點(diǎn)區(qū)別很容易混淆\h[1]。許多客戶端JavaScript對(duì)象和屬性與它們所表示的HTML標(biāo)簽和屬性同名。在HTML中,這些標(biāo)簽和屬性名可以使用大寫也可以是小寫,而在JavaScript中則必須是小寫。例如,在HTML中設(shè)置事件處理程序時(shí),onclick屬性可以寫成onClick,但在JavaScript代碼(或者XHTML文檔)中,必須使用小寫的onclick。2.1.2空格、換行符和格式控制符JavaScript會(huì)忽略程序中標(biāo)識(shí)(token)\h[2]之間的空格。多數(shù)情況下,JavaScript同樣會(huì)忽略換行符(2.5節(jié)提到了一種意外情形)。由于可以在代碼中隨意使用空格和換行,因此可以采用整齊、一致的縮進(jìn)來形成統(tǒng)一的編碼風(fēng)格,從而提高代碼的可讀性。除了可以識(shí)別普通的空格符(\u0020),JavaScript還可以識(shí)別如下這些表示空格的字符:水平制表符(\u0009)、垂直制表符(\u000B)、換頁符(\u000C)、不中斷空白(\u00A0)、字節(jié)序標(biāo)記(\uFEFF),以及在Unicode中所有Zs類別的字符\h[3]。JavaScript將如下字符識(shí)別為行結(jié)束符:換行符(\u000A),回車符(\u000D),行分隔符(\u2028),段分隔符(\u2029)。回車符加換行符在一起被解析為一個(gè)單行結(jié)束符。Unicode格式控制字符(Cf類\h[4]),比如“從右至左書寫標(biāo)記”(\u200F)和“從左至右書寫標(biāo)記”(\u200E)\h[5],控制著文本的視覺顯示,這對(duì)于一些非英語文本的正確顯示來說是至關(guān)重要的,這些字符可以用在JavaScirpt的注釋、字符串直接量和正則表達(dá)式直接量中,但不能用在標(biāo)識(shí)符(比如,變量名)中。但有個(gè)例外,零寬連接符(\u200D)和零寬非連接符(\uFEFF)\h[6]是可以出現(xiàn)在標(biāo)識(shí)符中的,但不能作為標(biāo)識(shí)符的首字符。上文也提到了,字節(jié)序標(biāo)記格式控制符(\uFEFF)被當(dāng)成了空格來對(duì)待。2.1.3Unicode轉(zhuǎn)義序列在有些計(jì)算機(jī)硬件和軟件里,無法顯示或輸入U(xiǎn)nicode字符全集。為了支持那些使用老舊技術(shù)的程序員,JavaScript定義了一種特殊序列,使用6個(gè)ASCII字符來代表任意16位Unicode內(nèi)碼。這些Unicode轉(zhuǎn)義序列均以\u為前綴,其后跟隨4個(gè)十六進(jìn)制數(shù)(使用數(shù)字以及大寫或小寫的字母A~F表示)。這種Unicode轉(zhuǎn)義寫法可以用在JavaScript字符串直接量、正則表達(dá)式直接量和標(biāo)識(shí)符中(關(guān)鍵字除外)。例如,字符é的Unicode轉(zhuǎn)義寫法為\u00E9,如下兩個(gè)JavaScript字符串是完全一樣的:"café"==="caf\u00e9"http://=>trueUnicode轉(zhuǎn)義寫法也可以出現(xiàn)在注釋中,但由于JavaScript會(huì)將注釋忽略,它們只是被當(dāng)成上下文中的ASCII字符處理,而且并不會(huì)被解析為其對(duì)應(yīng)的Unicode字符。2.1.4標(biāo)準(zhǔn)化Unicode允許使用多種方法對(duì)同一個(gè)字符進(jìn)行編碼。比如,字符“é”可以使用Unicode字符\u00E9表示,也可以使用普通的ASCII字符e跟隨一個(gè)語調(diào)符\u0301。在文本編輯器中,這兩種編碼的顯示結(jié)果一模一樣,但它們的二進(jìn)制編碼表示是不一樣的,在計(jì)算機(jī)里也不相等。Unicode標(biāo)準(zhǔn)為所有字符定義了一個(gè)首選的編碼格式,并給出了一個(gè)標(biāo)準(zhǔn)化的處理方式將文本轉(zhuǎn)換為一種適合比較的標(biāo)準(zhǔn)格式,JavaScript會(huì)認(rèn)為它正在解析的程序代碼已經(jīng)是這種標(biāo)準(zhǔn)格式,不會(huì)再對(duì)其標(biāo)識(shí)符、字符串或正則表達(dá)式作標(biāo)準(zhǔn)化處理。2.2注釋JavaScript支持兩種格式的注釋。在行尾“//”之后的文本都會(huì)被JavaScript當(dāng)做注釋忽略掉的。此外,“/*”和“*/”之間的文本也會(huì)當(dāng)做注釋,這種注釋可以跨行書寫,但不能有嵌套的注釋。下面都是合法的JavaScript注釋://這里是單行注釋/*這里是一段注釋*///這里是另一段注釋/**這又是一段注釋*這里的注釋可以連寫多行*/2.3直接量所謂直接量(literal),就是程序中直接使用的數(shù)據(jù)值。下面列出的都是直接量:12//數(shù)字1.2//小數(shù)"helloworld"http://字符串文本'Hi'//另一個(gè)字符串true//布爾值false//另一個(gè)布爾值/javascript/gi//正則表達(dá)式直接量(用做模式匹配)null//空第3章會(huì)詳細(xì)講解數(shù)字和字符串直接量。正則表達(dá)式直接量會(huì)在第10章講解。更多復(fù)雜的表達(dá)方式(參見4.2節(jié))可以寫成數(shù)組或?qū)ο笾苯恿?,例如:{x:1,y:2}//對(duì)象[1,2,3,4,5]//數(shù)組2.4標(biāo)識(shí)符和保留字標(biāo)識(shí)符就是一個(gè)名字。在JavaScript中,標(biāo)識(shí)符用來對(duì)變量和函數(shù)進(jìn)行命名,或者用做JavaScript代碼中某些循環(huán)語句中的跳轉(zhuǎn)位置的標(biāo)記。JavaScript標(biāo)識(shí)符必須以字母、下劃線(_)或美元符($)開始。后續(xù)的字符可以是字母、數(shù)字、下劃線或美元符(數(shù)字是不允許作為首字符出現(xiàn)的,以便JavaScript可以輕易區(qū)分開標(biāo)識(shí)符和數(shù)字)。下面是合法的標(biāo)識(shí)符:imy_variable_namev13_dummy$str出于可移植性和易于書寫的考慮,通常我們只使用ASCII字母和數(shù)字來書寫標(biāo)識(shí)符。然而需要注意的是,JavaScript允許標(biāo)識(shí)符中出現(xiàn)Unicode字符全集中的字母和數(shù)字。(從技術(shù)上講,ECMAScript標(biāo)準(zhǔn)也允許在標(biāo)識(shí)符的首字符后面出現(xiàn)Unicode字符集中的Mn類、Mc類和Pc類\h[7])。由此,程序員也可以使用非英語語言或數(shù)學(xué)符號(hào)來書寫標(biāo)識(shí)符:varsí=true;varπ=3.14;和其他任何編程語言一樣,JavaScript保留了一些標(biāo)識(shí)符為自己所用。這些“保留字”不能用做普通的標(biāo)識(shí)符,下面會(huì)講到。保留字JavaScript把一些標(biāo)識(shí)符拿出來用做自己的關(guān)鍵字。因此,就不能再在程序中把這些關(guān)鍵字用做標(biāo)識(shí)符了:JavaScript同樣保留了一些關(guān)鍵字,這些關(guān)鍵字在當(dāng)前的語言版本中并沒有使用,但在未來版本中可能會(huì)用到。ECMAScript5保留了這些關(guān)鍵字:此外,下面這些關(guān)鍵字在普通的JavaScript代碼中是合法的,但是在嚴(yán)格模式下是保留字:implementsletprivatepublicyieldinterfacepackageprotectedstatic嚴(yán)格模式同樣對(duì)下面的標(biāo)識(shí)符的使用做了嚴(yán)格限制,它們并不完全是保留字,但不能用做變量名、函數(shù)名或參數(shù)名:argumentsevalECMAScript3將Java的所有關(guān)鍵字都列為自己的保留字,盡管這些保留字在ECMAScript5中放寬了限制,但如果你希望代碼能在基于ECMAScript3實(shí)現(xiàn)的解釋器上運(yùn)行的話,應(yīng)當(dāng)避免使用這些關(guān)鍵字作為標(biāo)識(shí)符:JavaScript預(yù)定義了很多全局變量和函數(shù),應(yīng)當(dāng)避免把它們的名字用做變量名和函數(shù)名:JavaScript的具體實(shí)現(xiàn)可能定義獨(dú)有的全局變量和函數(shù),每一種特定的JavaScript運(yùn)行環(huán)境(客戶端、服務(wù)器端等)都有自己的一個(gè)全局屬性列表,這一點(diǎn)是需要牢記的。參照第四部分的Window對(duì)象來了解客戶端JavaScript中定義的全局變量和函數(shù)列表。2.5可選的分號(hào)和其他許多編程語言一樣,JavaScript使用分號(hào)(;)將語句(參見第5章)分隔開。這對(duì)增強(qiáng)代碼的可讀性和整潔性是非常重要的:缺少分隔符,一條語句的結(jié)束就成了下一條語句的開始,反之亦然。在JavaScript中,如果語句各自獨(dú)占一行,通常可以省略語句之間的分號(hào)(程序結(jié)尾或右花括號(hào)“}”之前的分號(hào)也可以省略)。許多JavaScript程序員(包括本書中的示例代碼)使用分號(hào)來明確標(biāo)記語句的結(jié)束,即使在并不完全需要分號(hào)的時(shí)候也是如此。另一種風(fēng)格就是,在任何可以省略分號(hào)的地方都將其省略,只有在不得不用的時(shí)候才使用分號(hào)。不管采用哪種編程風(fēng)格,關(guān)于JavaScript中可選分號(hào)的問題有幾個(gè)細(xì)節(jié)需要注意??紤]如下代碼,因?yàn)閮蓷l語句用兩行書寫,第一個(gè)分號(hào)是可以省略掉的:a=3;b=4;如果按照如下格式書寫,第一個(gè)分號(hào)則不能省略掉:a=3;b=4;需要注意的是,JavaScript并不是在所有換行處都填補(bǔ)分號(hào):只有在缺少了分號(hào)就無法正確解析代碼的時(shí)候,JavaScript才會(huì)填補(bǔ)分號(hào)。換句話講(類似下面代碼中的兩處異常),如果當(dāng)前語句和隨后的非空格字符不能當(dāng)成一個(gè)整體來解析的話,JavaScript就在當(dāng)前語句行結(jié)束處填補(bǔ)分號(hào)??匆幌氯缦麓a:varaa=3console.log(a)JavaScript將其解析為:vara;a=3;console.log(a);JavaScript給第一行換行處添加了分號(hào),因?yàn)槿绻麤]有分號(hào),JavaScript就無法解析代碼varaa。第二個(gè)a可以單獨(dú)當(dāng)做一條語句"a;",但JavaScript并沒有給第二行結(jié)尾填補(bǔ)分號(hào),因?yàn)樗梢院偷谌袃?nèi)容一起解析成“a=3;”。這些語句的分隔規(guī)則會(huì)導(dǎo)致一些意想不到的情形,這段代碼寫成了兩行,看起來是兩條獨(dú)立的語句:vary=x+f(a+b).toString()但第二行的圓括號(hào)卻和第一行的f組成了一個(gè)函數(shù)調(diào)用,JavaScript會(huì)把這段代碼看做:vary=x+f(a+b).toString();而這段代碼的本意并不是這樣。為了能讓上述代碼解析為兩條不同的語句,必須手動(dòng)填寫行尾的顯式分號(hào)。通常來講,如果一條語句以“(”、“[”、“/”、“+”或“-”開始,那么它極有可能和前一條語句合在一起解析。以“/”、“+”和“-”開始的語句并不常見,而以“(”和“[”開始的語句則非常常見,至少在一些JavaScript編碼風(fēng)格中是很普遍的。有些程序員喜歡保守地在語句前加上一個(gè)分號(hào),這樣哪怕之前的語句被修改了、分號(hào)被誤刪除了,當(dāng)前語句還是會(huì)正確地解析:varx=0//這里省略了分號(hào);[x,x+1,x+2].forEach(console.log)//前面的分號(hào)保證了正確地語句解析如果當(dāng)前語句和下一行語句無法合并解析,JavaScript則在第一行后填補(bǔ)分號(hào),這是通用規(guī)則,但有兩個(gè)例外。第一個(gè)例外是在涉及return、break和continue語句(參見第5章)的場景中。如果這三個(gè)關(guān)鍵字后緊跟著換行,JavaScript則會(huì)在換行處填補(bǔ)分號(hào)。例如,這段代碼:returntrue;JavaScript會(huì)解析成:return;true;而代碼的本意是這樣:returntrue;也就是說,在return、break和continue和隨后的表達(dá)式之間不能有換行。如果添加了換行,程序則只有在極特殊的情況下才會(huì)報(bào)錯(cuò),而且程序的調(diào)試非常不方便。第二個(gè)例外是在涉及“++”和“——”運(yùn)算符(見4.8節(jié))的時(shí)候。這些運(yùn)算符可以作為表達(dá)式的前綴,也可以當(dāng)做表達(dá)式的后綴。如果將其用做后綴表達(dá)式,它和表達(dá)式應(yīng)當(dāng)在同一行。否則,行尾將填補(bǔ)分號(hào),同時(shí)“++”或“——”將會(huì)作為下一行代碼的前綴操作符并與之一起解析,例如,這段代碼:x++y這段代碼將解析為"x;++y",而不是"x++;y"。\h[1]嚴(yán)格講XHTML是區(qū)分大小寫的,但由于瀏覽器有著非常較強(qiáng)大的糾錯(cuò)能力,即使文檔中包含很多不嚴(yán)格的大小寫,瀏覽器還是比較“寬容”地正確解析渲染。\h[2]請(qǐng)參照/wiki/Token。\h[3]Unicode對(duì)其所有字符做了分類,這種分類使用“通用類別值”表示,這里的"Zs"既是其中一種類別值,特指沒有標(biāo)志符號(hào)但不屬于控制或格式字符的空格字符。更多類別值的描述請(qǐng)參見/reports/tr44/中關(guān)于GeneralCategoryValues的內(nèi)容。\h[4]Cf是Unicode中的一種“通用類別值”,指代那些影響文本布局或文本處理操作但通常不會(huì)呈現(xiàn)的格式字符。\h[5]“從右至左書寫標(biāo)記”(RIGHT-TO-LEFTMARK)和“從左至右書寫標(biāo)記”(LEFT-TO-RIGHTMARK)均屬于雙向字符集語言,字符是帶有方向的,比如在阿拉伯語言中,標(biāo)點(diǎn)位于單詞的左側(cè),而不是我們通常熟悉的右側(cè)。\h[6]ZEROWIDTH(NON-)JOINER,零寬(非)連接符,指沒有寬度的不可見連接符,在蒙文、滿文、錫伯文等少數(shù)民族語言中會(huì)使用到。\h[7]Unicode對(duì)其所有字符做了分類,這種分類使用“通用類別值”表示,這里的"Mn"、"Mc"和"Pc"就是其中三種類別值,Mn表示基字符的修改中出現(xiàn)的非間距字符,Mc表示基字符的修改中影響了基字符標(biāo)志位的寬度的間距字符,Pc指連接兩個(gè)字符的連接符或標(biāo)點(diǎn)符號(hào)。更多類別值的描述請(qǐng)參見/reports/tr44/中關(guān)于GeneralCategoryValues的內(nèi)容。第3章類型、值和變量計(jì)算機(jī)程序的運(yùn)行需要對(duì)值(value)(比如數(shù)字3.14或文本"helloworld")進(jìn)行操作。在編程語言中,能夠表示并操作的值的類型稱做數(shù)據(jù)類型(type),編程語言最基本的特性就是能夠支持多種數(shù)據(jù)類型。當(dāng)程序需要將值保存起來以備將來使用時(shí),便將其賦值給(將值“保存”到)一個(gè)變量(variable)。變量是一個(gè)值的符號(hào)名稱,可以通過名稱來獲得對(duì)值的引用。變量的工作機(jī)制是編程語言的另一個(gè)基本特性。本章將詳細(xì)講解JavaScript中的類型、值和變量。這里的引言只做概述,你可以通過參照1.1節(jié)來幫助理解本章內(nèi)容。后續(xù)章節(jié)會(huì)更深入地講解。JavaScript的數(shù)據(jù)類型分為兩類:原始類型(primitivetype)和對(duì)象類型(objecttype)。JavaScript中的原始類型包括數(shù)字、字符串和布爾值,本章會(huì)有單獨(dú)的章節(jié)專門講述JavaScript中的數(shù)字(見3.1節(jié))和字符串(見3.2節(jié)),布爾值將會(huì)在3.3節(jié)講解。JavaScript中有兩個(gè)特殊的原始值:null(空)和undefined(未定義),它們不是數(shù)字、字符串和布爾值。它們通常分別代表了各自特殊

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論