- jQuery即學即用
- 王志剛編著
- 268字
- 2019-01-09 16:34:21
第2章 JavaScript語法基礎(chǔ)
無論使用何種JavaScript程序庫,都必須使用基本的JavaScript語句來調(diào)用。因此在學習jQuery前,有必要先了解一下JavaScript的基本知識。對那些已經(jīng)掌握了JavaScript編程知識的讀者,可以跳過本章,直接進入下一章的學習。
2.1 JavaScript的語言基礎(chǔ)
2.1.1 在HTML/xHTML文檔內(nèi)插入JavaScript
使用標記<script>…</script>可以在HTML/xHTML文檔的任意處,甚至在<HTML>之前插入JavaScript。如果要在聲明框架的網(wǎng)頁(框架網(wǎng)頁)中插入,則一定要在<frameset>之前插入;否則不會運行。
基本格式如下:
<script> <!-- ... (JavaScript代碼) ... //--> </script>
第2行和第4行的作用是讓不能識別<script>標記的瀏覽器忽略JavaScript代碼,一般可以省略。第4行前的雙反斜杠“//”是JavaScript的注釋標號。
另外一種插入JavaScript的方法是把JavaScript代碼寫到另一個文件中(此文件通常用“.js”作為擴展名),然后用格式為“<script src="javascript.js"></script>”的標記將其嵌入到文檔中。注意,一定要用“</script& gt;”標記。
<script>標記還有一個屬性“l(fā)anguage”(縮寫為“l(fā)ang”),說明腳本使用的語言,在JavaScript中為“l(fā)anguage="JavaScript"”。
相對于<script>,還有一個<server>標記,其中包含服務(wù)器端(Server Side)的腳本。本書只討論客戶端(Client Side)的JavaScript,即使用<script>標記包含的腳本。
如果要在瀏覽器的“地址”欄中執(zhí)行JavaScript語句,則使用如下格式:
javascript:<JavaScript語句>
這樣的格式也可以用在鏈接中:
<a href="javascript:<JavaScript語句>">...</a>
2.1.2 JavaScript基本語法
每一句JavaScript都有如下類似格式:
<語句>;
其中分號“;”是JavaScript語言的語句結(jié)束標識符。雖然現(xiàn)在很多瀏覽器允許使用回車符,但是使用分號仍然是很好的習慣。
語句塊用花括號“{ }”括起,其中可包含多個語句,在花括號外邊的語句塊被作為一個語句。語句塊可以嵌套,即一個語句塊中可以包含一個或多個語句塊。
1. 變量
從字面上看,變量是可變的量;從編程角度講,變量是用于存儲某種/某些數(shù)值的存儲器。所存儲的值可以是數(shù)字、字符或其他內(nèi)容。
(1)命名變量
命名變量有以下要求。
● 只包含字母、數(shù)字和/或下畫線。
● 以字母開頭。
● 不能過長。
● 不能與JavaScript保留字(Key Words或Reserved Words,凡是可以用來作為JavaScript命令的字都是保留字)重復(fù)。
變量區(qū)分大小寫,如variable和Variable是兩個不同的變量。
提示
命名變量最好避免用單個字母如“a”、“b”和“c”等,而使用能清楚表達該變量在程序中作用的詞語。這樣不僅他人更容易了解程序,而且在以后要修改程序時也很快會記得該變量的作用。變量名一般用小寫,如果由多個單詞組成,那么第1個單詞用小寫,其他單詞的第1個字母用大寫。例如,myVariable和myAnotherVariable。這樣做僅僅是為了美觀和易讀。因為JavaScript的一些命令都使用這種方法命名,如indexOf和charAt等。
(2)聲明變量
沒有聲明的變量不能使用,否則提示“未定義”。聲明變量可以用如下語句:
var <變量> [= <值>];
var是一個關(guān)鍵字(即保留字),用于聲明變量。最簡單的聲明方法是“var <變量>;”,這將為<變量>準備內(nèi)存,并為其賦初始值“null”。如果加上“= <值>”,則為<變量>賦予自定義初始值。
(3)數(shù)據(jù)類型
變量的數(shù)據(jù)類型如下。
● 整型
可以是正整數(shù)、0和負整數(shù),可以是十進制、八進制和十六進制。八進制數(shù)的表示方法是在數(shù)字前加“0”,如“0123”表示八進制數(shù) “123”;十六進制則加“0x”,如“0xEF”表示十六進制數(shù)“EF”。
● 浮點型
即“實型”。有資料顯示,某些平臺不能穩(wěn)定地支持浮點型變量,因此沒有需要就不要用該類型。
● 字符串型
用引號“" "”和“' '”包括的零個或多個字符,可用單引號或雙引號,用哪種引號開始就用哪種引號結(jié)束。單雙引號可嵌套使用,如'這里是"JavaScript教程"'。JavaScript中引號的嵌套只能有一層,如果需要多嵌套多層,則使用轉(zhuǎn)義字符。
由于一些字符在屏幕上不能顯示,或者JavaScript語法上已經(jīng)有了特殊用途,所以在使用這些字符時必須添加轉(zhuǎn)義字符。轉(zhuǎn)義字符用斜杠“\”開頭,如\' 單引號、\" 雙引號、\n換行符和\r回車。使用轉(zhuǎn)義字符可以實現(xiàn)引號的多重嵌套,如'Micro說:"這里是\"JavaScript教程\"。" '。
● 布爾型
常用于判斷,只有兩個值可選,即true(真)和false(假)。true和false是JavaScript的保留字,屬于常數(shù)。
● 對象
見2.2節(jié)。
由于JavaScript對數(shù)據(jù)類型的要求不嚴格,所以一般聲明變量時不需要聲明類型。而且即使聲明了類型,在代碼執(zhí)行過程中還可以為變量賦予其他類型的值。聲明類型可以用賦予初始值的方法實現(xiàn),如:
var aString = '';
這將把aString定義為具有空值的字符串型變量。
var anInteger = 0;
這將把anInteger定義為值為0 的整型。
(4)賦值變量
聲明一個變量后可以在任何時候用如下語法為其賦值:
<變量> = <表達式>;
其中“=”為“賦值符”,作用是把右邊的值賦給左邊的變量。
2. 常數(shù)
JavaScript的常數(shù)如下。
(1)null
一個特殊的空值。當變量未定義或者定義后未執(zhí)行賦值操作,則其值為“null”。試圖返回一個不存在的對象時也會出現(xiàn)null值。
(2)NaN “Not a Number”
當運算無法返回正確的數(shù)值時,會返回“NaN”值。該值非常特殊,因其不是數(shù)字,所以任何數(shù)均與其不等,甚至NaN本身也不等于NaN。
(3)true
布爾值真。
(4)false
布爾值假。
3. 表達式與運算符
(1)表達式
與數(shù)學中的定義相似,指具有一定值并用運算符連接常數(shù)和變量的代數(shù)式。一個表達式可以只包含一個常數(shù)或一個變量。
(2)運算符
運算符包括四則運算符、關(guān)系運算符、位運算符、邏輯運算符和復(fù)合運算符等,這些運算符及其從高到低的優(yōu)先級如表2-1所示。
表2-1 運算符及其從高到低的優(yōu)先級

提示
(1)所有與四則運算有關(guān)的運算符都不能用在字符串型變量中,可以使用 +和+= 連接兩個字符串。
(2)如果編程時不記得運算符的優(yōu)先級,可以使用括號( )。例如,(a == 0)||(b ==0)。
由于一些用來賦值的表達式有返回值,所以可加以利用。例如,語句a = b = c =10可以一次為3個變量賦值。
4. 語句
JavaScript的基本編程命令稱為“語句”。
(1)注釋
在腳本運行時忽略注釋語句,JavaScript注釋語句包括單行和多行注釋語句,單行注釋語句用雙反斜杠“//”開始,其后部分將被忽略;而多行注釋語句是用“/*”和 “*/”括起的一行或多行文本。程序執(zhí)行到“/*”處,將忽略其后的所有內(nèi)容,直到出現(xiàn)“*/”為止。
提示
養(yǎng)成寫注釋的習慣能節(jié)省寶貴的開發(fā)和維護程序的時間。在程序調(diào)試時,有時需要把一段代碼換成另一段或者暫時不需要一段代碼。這時最忌刪除代碼,應(yīng)用中使用注釋語句注釋暫時不需要的代碼。
(2)if語句
其格式如下:
if ( <條件> ) <語句1> [ else <語句2> ];
本語句類似條件表達式“?:”,當<條件>為真時執(zhí)行<語句1>;否則執(zhí)行<語句2>。與“?:”不同,if只是一條語句,不會返回數(shù)值。<條件>是布爾值,必須用尖括號括起。<語句1>和<語句2>只能是一個語句,多條語句可使用語句塊。
看下例:
if (a == 1) if (b == 0) alert(a+b); else alert(a-b);
本例試圖用縮進方法說明else對應(yīng)if (a == 1),但是實際上else與if (b == 0) 對應(yīng)。正確的代碼如下:
if (a == 1) { if (b == 0) alert(a+b); } else { alert(a-b); }
提示
一行代碼過長或者涉及比較復(fù)雜的嵌套,可以考慮用多行代碼。如上例,if (a == 1)后面沒有語句,而是換一行繼續(xù)寫。使用縮進也是很好的習慣,當一些語句與上面的一兩個語句有從屬關(guān)系時使用縮進能使程序更易讀。
(3)for語句
其格式如下:
for (<變量>=<初始值>; <循環(huán)條件>; <變量累加方法>) <語句>;
本語句的作用是重復(fù)執(zhí)行<語句>,直到<循環(huán)條件>為false為止。執(zhí)行過程是首先為<變量>賦<初始值>,然后判斷<循環(huán)條件>(應(yīng)該是一個關(guān)于變量的條件表達式)是否成立。如果成立,則執(zhí)行<語句>,即按<變量累加方法>累加<變量>;否則退出循環(huán),稱為“for循環(huán)”。
看下例:
for (i = 1; i < 10; i++) document.write(i);
本例首先為i賦初始值1,然后執(zhí)行document.write(i)語句(在文檔中寫i值)。重復(fù)i++,即i加1。循環(huán)直到i>=10結(jié)束,結(jié)果是在文檔中輸出“123456789”。
<語句>只能是一行語句,如果需要多條語句,則使用語句塊。
for循環(huán)沒有規(guī)定循環(huán)變量,每次循環(huán)一定要加1或減1,<變量累加方法>可以是任意的賦值表達式,如i+=3、i*=2和i-=j等都成立。
提示
適當使用for循環(huán)語句可簡化HTML文檔中大量有規(guī)律的重復(fù)部分,即使用for循環(huán)重復(fù)寫一些HTML代碼達到提高網(wǎng)頁下載速度的目的。不過應(yīng)在Netscape中重復(fù)嚴格測試,保證通過后上傳網(wǎng)頁,筆者多次試過因為用for循環(huán)向文檔重復(fù)寫HTML代碼而導(dǎo)致Netscape“猝死”,IE中沒有這種情況發(fā)生。
(4)while語句
其格式如下:
while (<循環(huán)條件>) <語句>;
while語句的作用是當滿足<循環(huán)條件>時執(zhí)行<語句>,一般情況下<語句>使用語句塊。因為除了要重復(fù)執(zhí)行某些語句之外,還需要一些改變<循環(huán)條件>所涉及變量值的語句;否則就會因為條件總是滿足而產(chǎn)生“死循環(huán)”。
(5)break和continue語句
有時在循環(huán)體內(nèi)需要立即跳出循環(huán)或跳過循環(huán)體內(nèi)其余代碼而執(zhí)行下一次循環(huán),break語句放在循環(huán)體內(nèi),作用是立即跳出循環(huán);continue語句放在循環(huán)體內(nèi),作用是中止本次循環(huán)并執(zhí)行下一次循環(huán)。如果循環(huán)的條件已經(jīng)不符合,則跳出循環(huán)。
看下例:
for (i = 1; i < 10; i++) { if (i == 3 || i == 5 || i == 8) continue; document.write(i); }
輸出結(jié)果為124679。
(6)switch語句
如果要把某些數(shù)據(jù)分類,如按優(yōu)、良、中和差分類學生的成績,則可以使用if語句:
if (score >= 0 && score < 60) { result = 'fail'; } else if (score < 80) { result = 'pass'; } else if (score < 90) { result = 'good'; } else if (score <= 100) { result = 'excellent'; } else { result = 'error'; }
使用過多的if語句導(dǎo)致程序看起來有些亂,使用switch語句是解決這個問題的最好方法:
switch (e) { case r1: ... [break;] case r2: ... [break;] ... [default: ...] }
上述代碼計算e的值(e為表達式),然后與下邊“case”后的r1、r2……比較。當找到一個相等于e的值時,則執(zhí)行該“case”后的語句,直到遇到break或switch語句塊結(jié)束(“}”);如果沒有一個值與e匹配,則執(zhí)行“default:”后邊的語句。如果沒有default塊,switch語句結(jié)束。
上述if代碼段用switch改寫后為:
switch (parseInt(score / 10)) { case 0: case 1: case 2: case 3: case 4: case 5: result = 'fail'; break; case 6: case 7: result = 'pass'; break; case 8: result = 'good'; break; case 9: result = 'excellent'; break; default: if (score == 100) result = 'excellent'; else result = 'error'; }
其中parseInt()方法的作用是取整,最后default段使用if語句是為了不把100 分作為錯誤處理(parseInt(100 / 10) == 10)。
2.2 對象化編程
JavaScript使用“對象化編程”,即面向?qū)ο缶幊獭ο蠡幊讨笇avaScript涉及的范圍劃分為對象,對象下面繼續(xù)劃分對象,直至詳盡為止。所有編程都以對象為出發(fā)點。小到一個變量,大到網(wǎng)頁文檔、窗口,甚至屏幕等都是對象。
2.2.1 對象的基本知識
對象是可以從JavaScript“勢力范圍”中劃分出來的一塊內(nèi)容,可以是一段文字、一幅圖片或一個表單(Form)等。每個對象有自己的屬性、方法和事件,對象的屬性反映該對象的某些特定性質(zhì),如字符串長度、圖像長寬及文本框(Textbox)中的文本等;對象的方法為該對象可執(zhí)行的操作,如表單的“提交”(Submit)和窗口的“滾動”(Scrolling)等;對象的事件為該對象可以響應(yīng)的操作,如提交表單產(chǎn)生表單的“提交事件”和單擊鏈接產(chǎn)生的“單擊事件”。有些對象沒有事件,有些只有屬性。引用對象的任一“性質(zhì)”使用“<對象名>.<性質(zhì)名>”方法。
2.2.2 基本對象
1.Number
即數(shù)字對象,這個對象用得很少,大多用于變量。
(1)屬性
● MAX_VALUE :Number.MAX_VALUE返回“最大值”。
● MIN_VALUE :Number.MIN_VALUE返回“最小值”。
● NaN :Number.NaN或NaN返回“NaN”。
● NEGATIVE_INFINITY :Number.NEGATIVE_INFINITY返回負無窮大,即比最小值還小的值。
● POSITIVE_INFINITY :Number.POSITIVE_INFINITY返回正無窮大,即比最大值還大的值。
(2)方法
toString() 用法為<數(shù)值變量>.toString()返回字符串形式的數(shù)值。如a == 123,則a.toString() == '123'。
2.String
即字符串對象,聲明一個字符串對象最簡單、快捷、有效和常用的方法是直接賦值。
(1)屬性
length :<字符串對象>.length,返回該字符串的長度。
(2)方法
● charAt() :<字符串對象>.charAt(<位置>),返回該字符串位于第<位置>位的單個字符。字符串中的第1個字符為第0位,第2個為第1位,最后一個字符為第length -1位。
● charCodeAt() :<字符串對象>.charCodeAt(<位置>),返回該字符串位于第<位置>位的單個字符的ASCII碼。
● fromCharCode() :String.fromCharCode(a, b, c...),返回一個字符串,其中每個字符的ASCII碼由a, b, c... 等來確定。
● indexOf() :<字符串對象>.indexOf(<另一個字符串對象>[, <起始位置>]),在<字符串對象>中查找<另一個字符串對象>(如果給出<起始位置>,則忽略之前的位置)。如果找到,返回其位置;否則返回-1。所有位置都從0開始。
● lastIndexOf() :<字符串對象>.lastIndexOf(<另一個字符串對象>[, <起始位置>])與indexOf() 相似,不過是從后邊開始查找的。
● split() :<字符串對象>.split(<分隔符字符>),返回一個數(shù)組,該數(shù)組從<字符串對象>中分離而來,<分隔符字符>決定了分離處,它本身不會包含在所返回的數(shù)組中。如'1&2&345&678'.split('&')返回數(shù)組1,2,345,678。
● substring() :<字符串對象>.substring(<始>[, <終>]),返回原字符串的子字符串,該字符串是原字符串從<始>位置到<終>位置的前一位置的一段,< 終> - <始> =返回字符串的長度(length)。如果沒有指定<終>或指定了超過字符串長度,則子字符串從<始>位置一直取到原字符串尾;如果指定的位置不能返回字符串,則返回空字符串。
● substr() :<字符串對象>.substr(<始>[, <長>]),返回原字符串的子字符串,該字符串是原字符串從<始>位置開始,長度為<長>的一段。如果沒有指定<長>或指定了超過字符串長度,則子字符串從<始>位置一直取到原字符串尾;如果指定的位置不能返回字符串,則返回空字符串。
● toLowerCase() :<字符串對象>.toLowerCase(),返回把原字符串所有大寫字母都變成小寫的字符串。
● toUpperCase() :<字符串對象>.toUpperCase(),返回把原字符串所有小寫字母都變成大寫的字符串。
3.Array
數(shù)組對象,是一個對象的集合,其中的對象可以是不同類型的。數(shù)組的每一個成員對象都有一個下標,用來表示它在數(shù)組中的位置(從0開始)。
數(shù)組的定義方法如下:
var <數(shù)組名> = new Array();
這樣定義了一個空數(shù)組,添加數(shù)組元素的語句如下:
<數(shù)組名>[<下標>] = ...;
注意這里的方括號用于括起數(shù)組的下標。
如果要在定義數(shù)組時直接初始化數(shù)據(jù),則使用如下語句:
var <數(shù)組名> = new Array(<元素1>, <元素2>, <元素3>...);
例如,var myArray = new Array(1, 4.5, 'Hi'); 定義了一個數(shù)組myArray,其中的元素是myArray[0] == 1、myArray[1] == 4.5和myArray[2] == 'Hi'。
如果元素列表中只有一個元素,而且又是一個正整數(shù),則定義一個包含<正整數(shù)>個空元素的數(shù)組。
提示
JavaScript只有一維數(shù)組,千萬不要用“Array(3,4)”這種方法來定義4 × 5 的二維數(shù)組,或者用“myArray[2,3]”這種方法來返回“二維數(shù)組”中的元素。如果使用“myArray[...,3]”這種形式的調(diào)用,則返回“myArray[3]”。要使用多維數(shù)組,則使用如下虛擬法:
var myArray = new Array(new Array(), new Array(), new Array(), ...);
其實這是一個一維數(shù)組,其中的每一個元素又是一個數(shù)組,調(diào)用這個“二維數(shù)組”的元素使用myArray[2][3] = ...語句。
(1)屬性
length :<數(shù)組對象>.length,返回數(shù)組的長度。即數(shù)組中的元素數(shù),等于數(shù)組中最后一個元素的下標加1,所以添加一個元素只需使用myArray[myArray.length] = ...語句。
(2)方法
● join() :<數(shù)組對象>.join(<分隔符>),返回一個字符串。該字符串把數(shù)組中的各個元素串起,用<分隔符>置于元素之間。這個方法不影響數(shù)組的原值。
● reverse() :<數(shù)組對象>.reverse(),使數(shù)組中的元素順序反過來。如果對數(shù)組[1, 2, 3]使用這個方法,則為[3, 2, 1]。
● slice() :<數(shù)組對象>.slice(<始>[, <終>]),返回一個數(shù)組,該數(shù)組是原數(shù)組的子集。始于<始>,終于<終>。如果未給出<終>,則子集一直取到原數(shù)組的結(jié)尾。
● sort() :<數(shù)組對象>.sort([<方法函數(shù)>]),使數(shù)組中的元素按照一定的順序排列。如果未指定<方法函數(shù)>,則按字母順序排列。在這種情況下,8排在9前;如果指定了<方法函數(shù)>,則按指定的方法排序。
如按升序排列數(shù)字:
function sortMethod(a, b) { return a - b; } myArray.sort(sortMethod);
按降序排列數(shù)字則把上面的“a - b”換為“b - a”。
4. Math
數(shù)學對象,提供數(shù)據(jù)的數(shù)學計算,在使用時記住“Math.<名>”這種格式。
(1)屬性
● E:返回常數(shù)e(2.718281828...)。
● LN2:返回2的自然對數(shù)(ln 2)。
● LN10:返回10的自然對數(shù)(ln 10)。
● LOG2E:返回以2為底的e的對數(shù)(log2e)。
● LOG10E:返回以10為底的e的對數(shù)(log10e)。
● PI:返回π(3.1415926535...)。
● SQRT1_2:返回1/2的平方根。
● SQRT2:返回2的平方根。
(2)方法
● abs(x):返回 x 的絕對值。
● acos(x):返回 x 的反余弦值(余弦值等于 x 的角度),用弧度表示。
● asin(x):返回 x 的反正弦值。
● atan(x):返回 x 的反正切值。
● atan2(x, y):返回復(fù)平面內(nèi)點(x, y)對應(yīng)的復(fù)數(shù)的幅角,用弧度表示,其值為 -π ~ π。
● ceil(x):返回大于等于 x 的最小整數(shù)。
● cos(x):返回 x 的余弦。
● exp(x):返回e的 x 次冪(ex)。
● floor(x):返回小于等于 x 的最大整數(shù)。
● log(x):返回 x 的自然對數(shù)(ln x)。
● max(a, b):返回a, b中較大的數(shù)。
● min(a, b):返回a, b中較小的數(shù)。
● pow(n, m):返回 n 的 m 次冪(nm)。
● random():返回大于0小于1的一個隨機數(shù)。
● round(x):返回x 四舍五入后的值。
● sin(x):返回x 的正弦。
● sqrt(x):返回x 的平方根。
● tan(x):返回x 的正切。
5. Date
日期對象,用于保存任意一個日期,范圍為0001年-9999年,并且可以精確到毫秒(1/1000秒)。在內(nèi)部日期對象是一個整數(shù),從1970年1月1日零時整開始計算到日期對象指日期的毫秒數(shù)。如果所指日期比1970年早,則是一個負數(shù);如果所有日期時間未指定時區(qū),則采用UTC(世界時)時區(qū),它與GMT(格林尼治時間)在數(shù)值上相同。
定義一個日期對象:
var d = new Date;
這個方法使d成為日期對象,并且已有初始值,即當前時間。如果要自定義初始值,可以使用:
var d = new Date(99, 10, 1); //99 年 10 月 1 日 var d = new Date(‘Oct 1, 1999’); //99 年 10 月 1 日
等方法。
以下有很多“g/set[UTC]XXX”這樣的方法,表示既有“getXXX”方法,又有“setxxx”方法。“get”獲得某個數(shù)值,而“set”設(shè)定某個數(shù)值。如果帶有“UTC”字母,則表示獲得/設(shè)定的數(shù)值基于UTC時間;否則基于本地時間或瀏覽器的默認時間。
如無說明,方法的使用格式為“<對象>.<方法>”。
日期對象的方法如下。
(1)g/set[UTC]FullYear():返回/設(shè)置年份,用4位數(shù)表示。如果使用“x.set[UTC] FullYear(99)”,則年份被設(shè)定為0099 年。
(2)g/set[UTC]Year():返回/設(shè)置年份,用兩位數(shù)表示。設(shè)定時瀏覽器自動加上“19”開頭,故使用 “x.set[UTC]Year(00)”把年份設(shè)定為1900 年。
(3)g/set[UTC]Month():返回/設(shè)置月份。
(4)g/set[UTC]Date():返回/設(shè)置日期。
(5)g/set[UTC]Day():返回/設(shè)置星期,0表示星期天。
(6)g/set[UTC]Hours():返回/設(shè)置小時數(shù),24小時制。
(7)g/set[UTC]Minutes():返回/設(shè)置分鐘數(shù)。
(8)g/set[UTC]Seconds():返回/設(shè)置秒鐘數(shù)。
(9)g/set[UTC]Milliseconds():返回/設(shè)置毫秒數(shù)。
(10)g/setTime():返回/設(shè)置時間,該時間是日期對象從1970 年1 月1 日零時整開始計算到日期對象所指的日期的毫秒數(shù)。如果要使某日期對象所指的時間推遲1 小時,則用 “x.setTime(x.getTime() + 60×60×1000);(1小時為60分,1分鐘為60秒,1秒鐘為1000毫秒)語句。
(11)getTimezoneOffset():返回日期對象采用的時區(qū)與格林尼治時間所差的分鐘數(shù),在格林尼治東方的時區(qū),該值為負。例如,中國時區(qū)(GMT+0800)返回“-480”。
(12)toString():返回一個字符串,描述日期對象所指的日期,這個字符串的格式類似 “Fri Jul 21 15:43:46 UTC+08002000”。
(13)toLocaleString():返回一個字符串,描述日期對象所指的日期,用本地時間表示格式,如“2000-07-21 15:43:46”。
(14)toGMTString():返回一個字符串,描述日期對象所指的日期,用GMT格式。
(15)toUTCString():返回一個字符串,描述日期對象所指的日期,用UTC格式。
(16)parse() 用法:Date.parse(<日期對象>);返回該日期對象的內(nèi)部表達方式。
6. 全局對象
全局對象從不現(xiàn)形,可以說是虛擬出來的,目的在于把全局函數(shù)“對象化”。在Microsoft JScript語言參考中稱為“Global對象”,但是引用其方法和屬性應(yīng)直接使用“xxx”,使用“Global.xxx”格式會出錯。
(1)屬性
NaN如前所述。
(2)方法
● eval():把括號內(nèi)的字符串作為標準語句或表達式執(zhí)行。
● isFinite() :如果括號內(nèi)的數(shù)字是有限的(Number.MIN_VALUE~Number.MAX_VALUE),則返回true;否則返回false。
● isNaN():如果括號內(nèi)的值是NaN,則返回true;否則返回false。
● parseInt():返回把括號內(nèi)的內(nèi)容轉(zhuǎn)換為整數(shù)之后的值,如果括號內(nèi)是字符串,則字符串開頭的數(shù)字部分被轉(zhuǎn)換為整數(shù);如果以字母開頭,則返回NaN。
● parseFloat():返回把括號內(nèi)的字符串轉(zhuǎn)換為浮點數(shù)之后的值,字符串開頭的數(shù)字部分被轉(zhuǎn)換為浮點數(shù);如果以字母開頭,則返回NaN。
● toString():<對象>.toString()把對象轉(zhuǎn)換為字符串,如果在括號中指定一個數(shù)值,則轉(zhuǎn)換過程中所有數(shù)值轉(zhuǎn)換為特定進制。
● escape():返回括號中的字符串經(jīng)過編碼后的新字符串,該編碼應(yīng)用于URL,把空格寫成“%20”這種格式。“+”不被編碼,如果要編碼,則用escape('...', 1)語句。
● unescape() : escape() 的反過程。解編括號中字符串成為一般字符串。
2.3 函數(shù)
函數(shù)是有返回值的對象或?qū)ο蟮姆椒ā?/p>
函數(shù)的內(nèi)部有一行或多行語句,這些語句在其他程序調(diào)用它時才執(zhí)行。在執(zhí)行一個函數(shù)時遇到return語句,函數(shù)停止執(zhí)行,并返回調(diào)用它的程序。如果return后帶有<值>,則退出函數(shù)的同時返回該值。
常見的函數(shù)有構(gòu)造函數(shù)(如Array()構(gòu)造一個數(shù)組)、全局函數(shù)(即全局對象中的方法)和自定義函數(shù)等。
(1)自定義函數(shù)
自定義函數(shù)使用以下語句:
function函數(shù)名([參數(shù)集]) { ... [return[ <值>];] ... }
其中不能省略用在function之后和函數(shù)結(jié)尾的花括號。
函數(shù)名與變量名的命名規(guī)則相同,即包含字母、數(shù)字和下畫線。并且以字母開始,不能與保留字重復(fù)等。
參數(shù)集可有可無,但括號一定要有。
● 參數(shù)
參數(shù)是函數(shù)外部向函數(shù)內(nèi)部傳遞信息的橋梁,如需要一個函數(shù)返回3 的立方,則要讓函數(shù)知道3這個數(shù)值。為此需要有一個變量來接收數(shù)值,即參數(shù)。
參數(shù)集是一個或多個用逗號分隔開的參數(shù)集合,如a, b, c。
在函數(shù)的內(nèi)部參數(shù)可以直接作為變量來使用,并可以用var語句來新建一些變量,但是這些變量不能被函數(shù)外部的過程調(diào)用。要使函數(shù)內(nèi)部的數(shù)據(jù)能被外部調(diào)用,則使用“return”返回值或全局變量。
● 全局變量
在Script的“根部”(非函數(shù)內(nèi)部)的var語句定義的變量即全局變量,它能在整個過程的任意處被調(diào)用和更改。
看下例:
function addAll(a, b, c) { return a + b + c; } var total = addAll(3, 4, 5);
這個例子建立一個名“addAll”的函數(shù),它的3個參數(shù)是a、b和c。作用是返回3個數(shù)的相加結(jié)果,在函數(shù)外部利用“var total = addAll(3, 4, 5);”接收函數(shù)的返回值。
函數(shù)一般沒有返回值,這種函數(shù)在一些比較強調(diào)嚴格的語言中叫做“過程”。例如,Basic類語言的“Sub”和Pascal語言的“procedure”。
● 屬性
Arguments是一個數(shù)組,反映外部程序調(diào)用函數(shù)時指定的參數(shù),其用法是直接在函數(shù)內(nèi)部調(diào)用“arguments”。
(2)自定義構(gòu)造函數(shù)
自定義構(gòu)造函數(shù)使用function,并使用其中的this來定義屬性:
function <構(gòu)造函數(shù)名> [(<參數(shù)>)] { ... this.<屬性名> = <初始值>; ... }
然后使用new構(gòu)造函數(shù)關(guān)鍵字來構(gòu)造變量:
var <變量名> = new <構(gòu)造函數(shù)名>[(<參數(shù)>)];
構(gòu)造變量后,<變量名>成為一個對象,其屬性使用this設(shè)定。
以下是一個從網(wǎng)上找到的搜集瀏覽器詳細資料的自定義構(gòu)造函數(shù)的例子:
function Is() { var agent = navigator.userAgent.toLowerCase(); this.major = parseInt(navigator.appVersion); //主版本號 this.minor = parseFloat(navigator.appVersion); //全版本號 this.ns = ((agent.indexOf('mozilla')!=-1) && ((agent.indexOf(‘spoofer’)==-1) && //是否Netscape (agent.indexOf('compatible') == -1))); this.ns2 = (this.ns && (this.major == 3)); //是否Netscape 2 this.ns3 = (this.ns && (this.major == 3)); //是否Netscape 3 this.ns4b = (this.ns && (this.minor < 4.04)); //是否Netscape 4 低版本 this.ns4 = (this.ns && (this.major >= 4)); //是否Netscape 4 高版本 this.ie = (agent.indexOf(“msie”) != -1); //是否IE this.ie3 = (this.ie && (this.major == 2)); //是否IE 3 this.ie4 = (this.ie && (this.major >= 4)); //是否IE 4 this.op3 = (agent.indexOf(“opera”) != -1); //是否Opera 3 this.win = (agent.indexOf(“win”)!=-1); //是否Windows版本 this.mac = (agent.indexOf(“mac”)!=-1); //是否Macintosh版本 this.unix = (agent.indexOf(“x11”)!=-1); //是否Unix版本 } var is = new Is();
這個構(gòu)造函數(shù)完整地搜集瀏覽器的信息,它為對象定義了多個屬性,如major、minor、ns、ie、win和mac等。把is變量定義為Is() 對象后,使用if (is.ns) 這種格式可以方便地知道瀏覽器的信息。從這個構(gòu)造函數(shù)中也可以看到它使用的是一般的JavaScript語句(例中為var語句)。
再來看一個使用參數(shù)的構(gòu)造函數(shù):
function myFriend(theName, gender, theAge, birthOn, theJob) { this.name = theName; this.isMale = (gender.toLowerCase == 'male'); this.age = theAge; this.birthday = new Date(birthOn); this.job = theJob } var Stephen = new myFriend('Stephen', 'Male', 18, 'Dec 22, 1982', 'Student');
從這個構(gòu)造函數(shù)可以看到參數(shù)的用法及不同屬性可用不同的數(shù)據(jù)型(例中的5個屬性分別為字符串、布爾值、數(shù)字、日期和字符串)和構(gòu)造函數(shù)來“構(gòu)造”屬性。如果使用足夠的“保護措施”來避免無限循環(huán),則可以用構(gòu)造函數(shù)自身來構(gòu)造自己的屬性。
(3)無名函數(shù)(function表達式)
在JavaScript中存在一種不用指定函數(shù)名定義函數(shù)的方法,用這種方法定義的函數(shù)稱為“無名函數(shù)”。
在JavaScript中使用無名函數(shù)現(xiàn)在已經(jīng)漸漸變?yōu)橹髁鳎趯W習編寫jQuery的插件前一定要掌握這種編程方法。定義無名函數(shù)的語法如下:
function(參數(shù)系列){函數(shù)的具體內(nèi)容};
實際上只是沒有指定函數(shù)名,其他與普通函數(shù)的定義沒有區(qū)別。但是因為沒有函數(shù)名,所以已經(jīng)不能使用通常的函數(shù)調(diào)用方法。調(diào)用方法如下:
var變量名= function(參數(shù)系列){函數(shù)的具體內(nèi)容}; 變量名(參數(shù)值);//函數(shù)調(diào)用
上面將無名函數(shù)賦值給變量,事件、數(shù)組和對象也可以這樣為變量賦值,為函數(shù)參數(shù)賦值等與通常的函數(shù)調(diào)用沒有區(qū)別。
2.3.1 閉包
閉包(closure)是JavaScript語言的一個難點,也是其特色之一,很多高級應(yīng)用(如jQurey)都要依靠閉包實現(xiàn)。
要理解閉包,首先必須理解JavaScript特殊的變量作用域,變量的作用域包括全局變量和局部變量。JavaScript語言的特殊之處就在于函數(shù)內(nèi)部可以直接讀取全局變量,如下例:
var n='test'; function f1(){ alert(n); } f1(); // test
在函數(shù)外部無法讀取函數(shù)內(nèi)的局部變量,如:
function f1(){ var n='test'; } alert(n); // error
注意函數(shù)內(nèi)部聲明變量時一定要使用var命令;否則實際上聲明了一個全局變量,如:
function f1(){ n='test'; } f1(); alert(n); // test
出于種種原因,有時需要得到函數(shù)內(nèi)的局部變量。但是必須通過變通方法實現(xiàn)。即在函數(shù)的內(nèi)部再定義一個函數(shù),如:
function f1(){ var n='test'; function f2(){ alert(n); // test } }
在上面的代碼中,函數(shù)f2被包括在函數(shù)f1內(nèi)部。這時f1內(nèi)部的所有局部變量對f2都是可見的,但是f2內(nèi)部的局部變量對f1不可見。這就是JavaScript語言特有的“鏈式作用域”結(jié)構(gòu)(chain scope),子對象會一級一級地向上查找所有父對象的變量。所以父對象的所有變量對子對象都是可見的,反之則不成立。
既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,即可在f1外部讀取其內(nèi)部變量,如:
function f1(){ var n='test'; function f2(){ alert(n); } return f2; } var result=f1(); result(); //test
上面的f2函數(shù)就是閉包。
各種專業(yè)文獻中有關(guān)閉包的定義非常抽象,比較難理解,其實閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。由于在JavaScript語言中只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解為定義在一個函數(shù)內(nèi)部的函數(shù)。所以在本質(zhì)上,閉包是連接函數(shù)內(nèi)部和外部的一座橋梁。
閉包的最大用處有兩個,一是前面提到的讀取函數(shù)內(nèi)部的變量;二是讓這些變量的值始終保存在內(nèi)存中,實現(xiàn)數(shù)據(jù)共享。下面再看幾個使用無名函數(shù)來定義閉包的例子:
var cnt = (function (){ var i=0; return function(){ alert(i); i++; } })(); cnt(); //顯示0 cnt(); //顯示1 cnt(); //顯示2
第1次調(diào)用[cnt()]后開始執(zhí)行無名函數(shù),執(zhí)行后變量i的值將保存在內(nèi)存中;第2次調(diào)用[cnt()]時將使用內(nèi)存中保存的i值,因此結(jié)果為1。
也可以向閉包內(nèi)部傳入?yún)?shù),如下:
var cnt = (function (num){ return function(){ alert(num); num++; } })(5); cnt(); //顯示5 cnt(); //顯示6 cnt(); //顯示7
另外,還可以在調(diào)用時指定參數(shù)值,如:
var cnt = (function (){ var i = 0; return function(num){ num += i; alert(num); num++; } })(); cnt(5); //顯示5 cnt(6); //顯示7 cnt(7); //顯示9
還可以以哈希表的形式定義多個返回的function函數(shù),如:
var cnt = (function (){ var i = 0; return { counter:function(){ i++; this.getValue(); }, getValue: function(){ return alert(i); } } })(); cnt.counter(); //顯示1 cnt.getValue(); //顯示1 cnt.counter(); //顯示2
2.3.2 基于prototype的對象
Prototype對象在JavaScript中實現(xiàn)面向?qū)ο缶幊痰闹饕δ埽ǔT谏深悾╟lass)和繼承已有類時使用。
在生成的function對象中使用Prototype對象在生成的function對象中追加內(nèi)容,稱為“基于prototype的對象”,下面是一個簡單的例子:
var cnt = function (){}; cnt.prototype = { i : 0; num:function(){ alert(this.i); this.i++; } }; var c = new cnt(); c.num(); //顯示0 c.num(); //顯示1 c.num(); //顯示2
作為高級的JavaScript編程方法,在編寫庫或框架時會用到閉包和Prototype對象。
2.3.3 with語句和this對象
1. with語句
該語句為一個或一組語句指定默認對象。
用法:
with (<對象>) <語句>;
with語句通常用來縮短特定情形下必須寫的代碼量,在下例中注意Math的重復(fù)使用:
x = Math.cos(3 * Math.PI) + Math.sin(Math.LN10); y = Math.tan(14 * Math.E);
當使用with語句時,代碼變得更短且更易讀:
with (Math) { x = cos(3 * PI) + sin(LN10); y = tan(14 * E); }
2. this對象
該對象返回當前對象,在不同處this代表不同的對象。如果在JavaScript的主程序,而不在任何function和事件處理程序中使用this,則代表window對象;如果在with語句塊中使用this,則代表with所指定的對象;如果在事件處理程序中使用this,則代表發(fā)生事件的對象。
一個常用的this用法如下:
<script> ... function check(formObj) { ... } ... </script> <body ...> ... <form ...> ... <input type="text" ... onchange="check(this.form)"> ... </form> ... </body>
這個用法常用于檢測表單輸入的有效性。
2.4 事件處理
事件處理是對象化編程的一個很重要的環(huán)節(jié),沒有事件處理,程序就會缺乏靈活性。事件處理的過程即發(fā)生事件,然后啟動事件處理程序做出反應(yīng),必須首先告訴對象可能發(fā)生的事件及其處理程序;否則這個流程就不能進行下去。事件處理程序可以是任意JavaScript語句,但是一般用特定的自定義函數(shù)(function)來處理事件。
2.4.1 指定事件處理程序
指定事件處理程序有如下3種方法。
(1)直接在HTML標記中指定,這種方法運用最為普遍,格式如下:
<標記 ... ... 事件="事件處理程序" [事件="事件處理程序" ...]>
看下例:
<body ... onload="alert('網(wǎng)頁讀取完成,請慢慢欣賞!')" onunload="alert(' 再見!')">
這樣定義的<body>標記能使讀取文檔后彈出一個對話框,提示“網(wǎng)頁讀取完成,請慢慢欣賞!”,并且在用戶退出文檔(或者關(guān)閉窗口或者到另一個頁面)時彈出“再見!”。
(2)編寫特定對象特定事件的JavaScript,這種方法用得比較少。但是在某些場合很好用,格式如下:
<script language="JavaScript" for="對象" event="事件"> ... (事件處理程序代碼) ... </script>
例如:
<script language="JavaScript" for="window" event="onload"> alert('網(wǎng)頁讀取完成,請慢慢欣賞!'); </script>
(3)在JavaScript中聲明,格式如下:
<事件主角 - 對象>.<事件> = <事件處理程序>;
用這種方法要注意 “事件處理程序”是真正的代碼,而不是字符串形式的代碼。如果事件處理程序是一個自定義函數(shù),如無使用參數(shù)的需要,則不要加圓括號 “()”。例如:
... function ignoreError() { return true; } ... window.onerror = ignoreError; // 沒有使用“()”
這個例子將ignoreError() 函數(shù)定義為window對象的onerror事件的處理程序,作用是忽略該window對象下任何錯誤(由引用不允許訪問的location對象產(chǎn)生的“沒有權(quán)限”錯誤不能被忽略)。
2.4.2 常用事件
常用事件如下。
(1)onblur事件:發(fā)生在窗口失去焦點時。
應(yīng)用于window對象。
(2)onchange事件:發(fā)生在文本輸入?yún)^(qū)的內(nèi)容被更改,然后焦點從文本輸入?yún)^(qū)移走之后。捕捉此事件主要用于實時檢測輸入的有效性,或者立即改變文檔內(nèi)容。
應(yīng)用于Password、Select、Text和Textarea對象。
(3)onclick事件:發(fā)生在對象被單擊時。
一個普通按鈕對象(Button)通常會有onclick事件處理程序,因為這種對象不能從用戶處得到任何信息。為按鈕添加onclick事件處理程序可以模擬另一個“提交”按鈕的方法是在事件處理程序中更改表單的action、target、encoding和method等一個或多個屬性,然后調(diào)用表單的submit()方法。
在Link對象的onclick事件處理程序中返回false值,能阻止瀏覽器打開此鏈接。如果有一個鏈接為<a onclick="return false">Go!</a>,那么無論用戶如何單擊,都不會打開www.a.com網(wǎng)站;除非用戶禁止瀏覽器運行JavaScript。
應(yīng)用于Button、Checkbox、Image、Link、Radio、Reset和Submit對象。
(4)onerror事件:發(fā)生在錯誤發(fā)生時,其事件處理程序通常叫做“錯誤處理程序”(Error Handler)。要忽略一切錯誤,則使用如下代碼:
function ignoreError() { return true; } window.onerror = ignoreError;
應(yīng)用于window對象。
(5)onfocus事件:發(fā)生在窗口得到焦點時。
應(yīng)用于window對象。
(6)onload事件:發(fā)生在文檔全部下載完畢時,意味著不但HTML文件,而且包含的圖片、插件、控件和小程序等全部內(nèi)容都下載完畢。本事件是window事件,但是在HTML中指定事件處理程序時將寫在<body>標記中。
應(yīng)用于window對象。
(7)onmousedown事件:發(fā)生在用戶把鼠標放在對象上并按下鼠標鍵時,參考onmouseup事件。
應(yīng)用于Button和Link對象。
(8)onmouseout事件:發(fā)生在鼠標離開對象時,參考onmouseover事件。
應(yīng)用于Link對象。
(9)onmouseover事件:發(fā)生在鼠標進入對象范圍時,這個事件和onmouseout事件加上圖片的預(yù)讀,即可實現(xiàn)當鼠標移到圖像鏈接上更改圖像的效果。有時在指向一個鏈接時狀態(tài)欄中未顯示地址,而顯示其他信息,并且看起來這些信息可以隨時更改。這個效果的實現(xiàn)如下:
<a href="..." onmouseover="window.status='Click Me Please!'; return true;" onmouseout="window.status=''; return true;">
應(yīng)用于Link對象。
(10)onmouseup事件:發(fā)生在用戶把鼠標放在對象上且按下鼠標鍵,然后放開鼠標鍵時。如果按下鼠標鍵時,鼠標并不在放開鼠標的對象上,則不會發(fā)生本事件。
應(yīng)用于Button和Link對象。
(11)onreset事件:發(fā)生在單擊表單的“重置”按鈕時,通過在事件處理程序中返回false值可以阻止表單重置。
應(yīng)用于Form對象。
(12)onresize事件:發(fā)生在調(diào)整窗口大小時。
應(yīng)用于window對象。
(13)onsubmit事件:發(fā)生在單擊表單中的“提交”按鈕時,可以使用該事件來驗證表單的有效性,并且通過在事件處理程序中返回false值可以阻止提交表單。
應(yīng)用于Form對象。
(14)onunload事件:發(fā)生在用戶退出文檔(或者關(guān)閉窗口,或者打開另一個頁面)時,與onload一樣,要放在HTML中的<body>標記中。
有的Web Masters用這個方法來彈出“調(diào)查表單”,以“強迫”來訪者填寫;有的彈出廣告窗口,誘使來訪者單擊鏈接。
應(yīng)用于Window對象。
2.5 DOM
W3C已于2000年11月13日推出了DOM level 2規(guī)范,DOM(Document Object Model,文檔對象模型)是HTML和XML文檔的編程接口規(guī)范。由于與平臺和語言無關(guān),因而可以用多種語言并在多種平臺上實現(xiàn)。
該規(guī)范定義了HTML和XML文件在內(nèi)存中的文檔結(jié)構(gòu),提供了訪問和存取HTML和XML文件的方法。利用DOM規(guī)范,可以實現(xiàn)DOM和XML文檔之間的相互轉(zhuǎn)換,并對相應(yīng)DOM文檔的內(nèi)容執(zhí)行遍歷或其他操作。要想自由地操作XML文件,則會用到DOM規(guī)范。
DOM的原理簡單地說就是通過解析XML文檔,為其在邏輯上建立一個樹模型。樹的節(jié)點是一個個對象,通過存取這些對象即可操作XML文檔中的內(nèi)容。
在jQuery中使用DOM來處理HTML/xHTML文檔,提供取得父節(jié)點和子節(jié)點的函數(shù)。
2.6 Ajax
Ajax(Asynchronous JavaScript and XML)用來描述一組技術(shù),使瀏覽器可以為用戶提供更為自然的瀏覽體驗。在Ajax之前,Web站點強制用戶進入提交/等待/重新顯示范例,用戶的動作總是與服務(wù)器的“思考時間”同步。Ajax提供與服務(wù)器異步通信的能力,從而使用戶從請求/響應(yīng)的循環(huán)中解脫出來。借助于Ajax可以在用戶單擊按鈕時使用JavaScript和DHTML立即更新UI,并向服務(wù)器發(fā)出異步請求,以執(zhí)行更新或查詢數(shù)據(jù)庫。當請求返回時,就可以使用JavaScript和CSS來相應(yīng)地更新UI,而不是刷新整個頁面。最重要的是,用戶甚至不知道瀏覽器正在與服務(wù)器通信,Web站點看起來是即時響應(yīng)的。
雖然Ajax所需的基礎(chǔ)架構(gòu)已經(jīng)出現(xiàn)了一段時間,但直到Google公司在Google Maps中應(yīng)用該技術(shù),這種異步請求技術(shù)的真正威力才廣為網(wǎng)絡(luò)技術(shù)人員所認知。能夠擁有一個響應(yīng)極其靈敏的Web站點確實激動人心,因為它最終允許開發(fā)人員和設(shè)計人員使用標準的HTML/CSS/JavaScript堆棧創(chuàng)建“桌面風格”(desktop-like)且可用性強的Web應(yīng)用程序。
根據(jù)Ajax提出者Jesse James Garrett的建議,Ajax技術(shù)應(yīng)該包含如下特征。
(1)使用xHTML+CSS來表示信息。
(2)使用JavaScript操作DOM實現(xiàn)動態(tài)顯示及交互。
(3)使用XML和XSLT執(zhí)行數(shù)據(jù)交換及相關(guān)操作。
(4)使用XMLHttpRequest對象與Web服務(wù)器執(zhí)行異步數(shù)據(jù)交換。
(5)使用JavaScript將所有內(nèi)容綁定在一起。
因此Ajax技術(shù)類似DHTML或LAMP,不是指一種單一的技術(shù),而是有機地利用了一系列相關(guān)的技術(shù),并且與服務(wù)器端應(yīng)用程序(PHP、Perl、Java和DB等)組合來構(gòu)建Web應(yīng)用程序的解決方案總稱。
- 嵌入式系統(tǒng)及其開發(fā)應(yīng)用
- Hands-On Internet of Things with MQTT
- Security Automation with Ansible 2
- 21天學通ASP.NET
- CorelDRAW X4中文版平面設(shè)計50例
- AutoCAD 2012中文版繪圖設(shè)計高手速成
- Mastering ServiceNow Scripting
- 計算機組網(wǎng)技術(shù)
- Excel 2010函數(shù)與公式速查手冊
- 云計算和大數(shù)據(jù)的應(yīng)用
- 學練一本通:51單片機應(yīng)用技術(shù)
- AI的25種可能
- 在實戰(zhàn)中成長:C++開發(fā)之路
- Photoshop CS4數(shù)碼照片處理入門、進階與提高
- ARM體系結(jié)構(gòu)與編程