Transcript 04-進階資料型態
第四章 進階資料型態 張智星 [email protected] http://mirlab.org/jang 台大資工系 多媒體檢索實驗室 JavaScript 程式設計與應用:用於網頁用戶端 本章大綱 大綱 本章說明 JavaScript 的一些進階資料型態,包含 陣列、字典物件、自訂物件等。掌握這一些進階 資料型態,你的程式碼就會更簡潔易懂。 主題 4-1:陣列物件的簡介 4-2:陣列物件的方法 4-3:字典物件 4-4:自訂物件 2/38 JavaScript 程式設計與應用:用於網頁用戶端 4-1:陣列物件的簡介 本章介紹陣列物件及相關函式的使用。 3/38 JavaScript 程式設計與應用:用於網頁用戶端 陣列基本簡介 陣列 (Arrays) 是 JavaScript 提供的內建物件 (Builtin Object) 之一,其功能強大,可大幅度簡化你的 程式碼。 陣列是一個變數,但它可以儲存許多種不同的值 (可以是字串、數值,或是各種物件) 我們可以使用索引 (Index)來存取每一個元素的值, 索引從 0 開始,例如陣列 A 的第一個元素為 A[0], 第五個元素為 A[4],依此類推,這是最常用的陣列 元素存取方式。(這部分和C語言是一致的。) 4/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-1 主題:示範陣列的基本建構 連結:array01.htm 程式碼重點 myArray = new Array(); // 產生一個空的陣列 myArray[0] = "This is a test"; // 加入第 1 個元素 myArray[1] = 3.1415926; // 加入第 2 個元素 myArray[2] = "The last element"; // 加入第 3 個元素 說明 要使用陣列變數時,需先宣告,但可以不用設定 陣列的元素個數。 5/38 JavaScript 程式設計與應用:用於網頁用戶端 指定陣列元素值 另外兩種指定陣列元素的方法 可將元素值一次指定完成: myArray = new Array("This is a test", 3.1415926, "The last element"); 也可以使用更簡單的方法: myArray = ["This is a test", 3.1415926, "The last element"]; 6/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-2 主題:定義js檔案,並印出陣列的所有內容。 連結:listArray.js 程式碼 說明 function listArray(array, arrayName){ for (var i=0; i<array.length; i++) { document.write(arrayName+“[”+i+“] = ”); document.write("<font color=green>"+array[i]+"</font><br>"); } } 其中 array 代表傳入函數的陣列,arrayName 則是此陣列 的名稱,而 array.length 則是陣列 array 的元素個數。 7/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-3 主題:利用listArray.js印出陣列元素 連結:array02.htm 程式碼重點 <script src=listArray.js></script> listArray(myArray, "myArray"); 說明 利用重點程式碼第一行,引入js檔中的程式碼, 這種方式,可以讓我們在不同的網頁導入相同的 函式,請見後續章節有關於「自訂函數」的說明。 8/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-4 主題:用亂數點選字串陣列的元素。 連結: randomText.htm 程式碼重點 index = Math.floor(Math.random()*text.length); 說明 Math.random() 會傳回一個介於 0 和 1 之間的亂數。 因此 Math.random()*text.length 會產生一個介於 0 和 text.length 之間的亂數(帶有小數)。 最後,Math.floor(Math.random()*text.length) 會產生一 個介於 0 和 text.length-1 之間的整數(包含頭尾),所 以可以用來選取 text 陣列中的一個元素。 9/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-5 主題:利用亂數點選背景 MIDI 音樂 連結: randomMusic.htm 說明 在上述範例中,我們使用了三個陣列,分別用來 儲存 midi 網址、歌曲名稱、歌手姓名。 更好的作法,是用一個陣列來存放這些資料,其 中每一個元素代表一首歌曲的資料,包含三個欄 位(midi 網址、歌曲名稱、歌手姓名),這樣的資 料結構比較模組化。 10/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-6 主題:利用亂數點選影像及背景 MIDI 音樂 連結: randomImage.htm 說明 利用和範例4-4的方式,我們可以隨機產生一張照 片,同時也播放隨機背景音樂。 11/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-7 主題:利用亂數合成訊息,並自動更新 連結: punchme.htm 程式碼重點 <meta http-equiv="Refresh" content="3"> 說明 重點程式碼會讓瀏覽器每 3 秒就重新載入網頁。 範例中用了 onMouseDown 和 onMouseUp 的事 件,以便即時更換影像,達到趣味性的效果。 12/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-8 主題:有快取效果(Cache)的 JavaScript 網頁 連結: rotateImage.htm 說明 一旦知道影像物件的網址,JavaScript 會先將影 像資料抓回來,等要要呈現影像時,就可以直接 從客戶端電腦的記憶體中抓取,省卻了直接從網 路抓取的時間,減少了使用者的等待時間,達到 「快取」(Cache)的效果。 如果 imageArray 只是用來存放影像的網址,而 不是存放一個影像物件,那就不會有快取的效果。 13/38 JavaScript 程式設計與應用:用於網頁用戶端 4-2:陣列物件的方法 本小節介紹陣列物件方法的相關使用 14/38 JavaScript 程式設計與應用:用於網頁用戶端 陣列物件方法 方法 說明 concat() 傳回一個由兩個或兩個以上陣列並排而成的新陣列 join() 傳回一個字串值,它是由陣列中的所有元素串連在一起所組成,並且 用特定的分隔字元來分隔 pop() 移除陣列的最後一個元素,並將它傳回 push() 附加新元素到陣列尾部,並傳回陣列的新長度 reverse() 傳回一個元素位置反轉的陣列 shift() 移除陣列的第一個元素,並將它傳回 slice() 傳回陣列的一個區段 splice() 移除陣列中的元素,並依需要在原位插入新元素,然後傳回被刪除的 元素 sort() 傳回一個元素已排序過的陣列 toString() 傳回一個物件(或陣列)的字串表示法 unshift() 在陣列開始處插入指定的元素,並傳回此陣列 15/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-10 主題:使用陣列方法: sort() 和 reverse() 連結: arraySort01.htm 程式碼重點 listArray(myArray.sort(), "myArray"); listArray(myArray.reverse(), "myArray"); 說明 sort() 會先將數值轉成字串,再進行字串的排序。 若要進行數值的排序,就必須定義一個比較函數, 並將此比較函數送進 sort(),請見下個範例。 16/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-11 主題:定義 sort() 的比較函數 連結: arraySort02.htm 程式碼重點 function comparisonFunction(a, b){ return(a-b); } 說明 a和b會被轉換為數值型態,sort()方法依照比較函數的回 傳值來排序。 當我們使用加號將陣列和字串並排時,JavaScript 會將陣 列轉換成由逗號隔開的字串。 如果陣列的每一個元素都是數值,JavaScript 在執行 sort() 時,會依照字串來排序,這是特別要注意的地方。 17/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-12 主題:陣列方法:pop(), push(), shift(), unshift() 連結: arrayPop01.htm 程式碼重點 cmd cmd cmd cmd = = = = 'myPet.unshift("狗", "豬")'; 'elementCount = myPet.push("龍", "蛇")'; "shifted = myPet.shift()"; 'myPet.unshift("狗", "豬")'; 說明 範例使用eval(cmd);的方式將字串變成可執行的 程式碼。 18/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-13 主題:使用陣列方法:toString() 和 join() 連結: arrayJoin01.htm 程式碼重點 document.writeln("myPet.toString()=“+myPet.toString()+"<br>"); document.writeln("myPet.join()="+myPet.join()+"<br>"); document.writeln("myPet.join(',')="+myPet.join(',')+"<br>"); document.writeln("myPet.join('+')="+myPet.join('+')+"<br>"); 說明 從範例可以看出,myPet.toString() 和 myPet.join() 得到的結果是一樣的。 19/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-14 主題:陣列的方法:split()和concat() 連結: arrayConcat01.htm 程式碼重點 array1=str1.split('、'); // 將字串拆成陣列 array3=array1.concat(array2); 說明 字串物件由split()中的字串”、”分割成陣列。 Concat可以使兩陣列結合在一起形成新的陣列。 20/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-15 主題:使用 prototype 來定義陣列新的方法 連結:prototype01.htm 程式碼重點 Array.prototype.max = arrayMax; 說明 我們使用 Array.prototype.max 來定義自訂方法 max() 所對應的函數是 arrayMax()。 在函數 arrayMax() 中,this 代表此方法所對應的 物件。 21/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-16 主題:列出所有陣列物件屬性的測試 連結:arrayProp01.htm 程式碼重點 for (prop in myArray) document.write("<br>myArray." + prop + " = " + myArray[prop]); 說明 JavaScript 會把 0, 1, 2 當成是陣列物件的性質。 我們在取用陣列的元素時,還是必須使用 myArray[2] 或 是 myArray[“2”] 等,而不能使用 myArray.2。 22/38 JavaScript 程式設計與應用:用於網頁用戶端 4-3:字典物件 本小節介紹字典物件的建構與使用。 目前只能用在IE。 23/38 JavaScript 程式設計與應用:用於網頁用戶端 字典物件介紹 一般的陣列是以循序的數值來進行索引,但 是字典物件(Dictionary)是以字串來進行索 引(或是以字串為鍵值)。 要產生一個字典物件,必須先使用 new ActiveXObject(“Scripting.Dictionary”) 產生一 個空的字典物件,然後再使用 Add() 方法來 將對應關係一個一個加進去。 字典物件又稱為關聯陣列(Associative Arrays),代表兩個字串之間的關聯關係。 24/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-17 主題:字典物件的建構方法 連結:dict01.htm 程式碼重點 capitalOf = new ActiveXObject("Scripting.Dictionary"); capitalOf.Add("Taiwan", "Taipei"); document.writeln("capitalOf(\"Taiwan\")="+capitalOf("Ta iwan")+ "<br>"); 說明 在上述範例中,每個字典物件的索引是一個字串。 請注意是 capitalOf("Taiwan") 是用小括弧,不是 用中括弧(中括弧是用在陣列物件)。 25/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-18 主題:列印字典變數 連結:listDict.js 程式碼 說明 function listDict(dict, dictName){ allKeys = (new VBArray(dict.Keys())).toArray(); for (var i=0; i<dict.Count; i++) document.writeln(dictName+"(\"<font color=blue>"+allKeys[i]+"</font>\") = <font color=red>"+dict(allKeys[i])+"</font><br>"); } dict.Count 代表此字典物件的項目個數,而 dict.Keys() 將會在之後範例說明。 26/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-19 主題:字典物件的 Remove()、Key()和Item()方法 連結: dict02.htm 程式碼重點 countryOf.Remove("Tokyo"); countryOf.Key("Taipei") = "Hsinchu"; Hsinchu countryOf.Item("Tokyo") = "Nippon“; 說明 Remove()方法移除 Tokyo 鍵值(及對應的字串)。 Key()方法將 Taipei 鍵值改成 Hsinchu Item() 方法Taipei 鍵值改成 Hsinchu 27/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-20 主題:使用 Keys() 和 Items() 取出字典物件的鍵值 和對應值 連結:dict03.htm 程式碼重點 allKeys = (new VBArray(capitalOf.Keys())).toArray(); allItems = (new VBArray(capitalOf.Items())).toArray(); 說明 由Keys()或Items()所傳回的物件並不能直接使用,必須 轉成VBArray 後再用toArray()轉成JavaScript 的陣列。 因為字典物件本來就是 VBScript 的內建物件,使得 JavaScript的字典物件籠罩在 VBScript 的陰影下。 28/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-21 主題:使用 Exists() 和 RemoveAll() 的字典 物件的方法 連結:dict04.htm 程式碼重點 if (capitalOf.Exists(key)) {…} capitalOf.RemoveAll(); 說明: Exists()測試key是否為此字典物件的鍵值。 RemoveAll()移除字典物件中所有的項目。 29/38 JavaScript 程式設計與應用:用於網頁用戶端 4-4:自訂物件 本小節介紹使用者如何自訂物件。 30/38 JavaScript 程式設計與應用:用於網頁用戶端 JavaScript 的物件 JavaScript 的物件可分三類: 內建的物件(如日期、數學等物件) 根據網頁的內容所建立的文件物件模型 (Document Object Model ,簡稱 DOM) 使用者自訂的物件 31/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-22 主題:自訂簡單的物件示範 連結: object01.htm 程式碼重點 student = new Object(); student.name = "Timmy"; student.age = "25"; student.phone = "575-1114"; 說明 範例中我們使用 new Object() 來產生一個使用者 自訂的物件,並設立此物件的三個性質。 32/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-23 主題:寫js檔來列出物件所有性質 連結:listProp.js 程式碼 function listProp(obj, objName) { for (var i in obj) document.writeln(objName+".<font color=red>"+i+"</font> = <font color=green>"+obj[i]+"</font><br>"); } 說明 js檔的使用方式:listProp(物件,物件名稱字串)。 33/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-24 主題:使用「單列指定」的方式,來指定一 個物件的所有屬性。 連結:object02.htm 程式碼重點 student = {"name":"Timmy", "age":25, "phone":"575-1114"} 說明 使用此種「單列指定」的好處是可以指定含有空 格的性質,但是若要存取此(含有空格的)性質, 則必須使用「物件["性質"]」的方式來進行,而 不能使用「物件.性質」的方式。 34/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-25 主題:以 in 運算子測試物件的欄位是否存在 連結:in01.htm 程式碼重點 if (field in student) document.write(field + " is a field of student<br>"); 說明 以「 "性質" in 物件」來說,如果這個物件擁有 性質,就會回傳true,不存在則回傳false。 35/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-26 主題:示範自訂較為複雜的物件 連結:object03.htm 程式碼重點 說明 function student(inputName, inputStudentID, inputAge) { this.name = inputName; this.studentID = inputStudentID; this.age = inputAge; this.display = displayStudent; } 範例中定義此物件的「建構子」(Constructor, 也就是用來創造物件的函數)來自訂物件。 this代表此範例所建構的物件。 36/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-27 主題:示範自訂巢狀式物件 連結:object04.htm 說明 範例中定義了student(學生)和course(課程)兩個 物件。 在student中的this.course = inputCourse;將 course物件放到student物件中,形成巢狀物件。 37/38 JavaScript 程式設計與應用:用於網頁用戶端 範例4-28 主題:以陣列來存放自訂的物件 連結:expenseTable.htm 程式碼重點 expense[i++]=new expenseItem( 200, "每天", 365/12, "餐費"); expense[i++]=new expenseItem(3000, "每月", 1, "房租"); 說明 i++ 先用 i的值執行完該列敘述,再把 i 的值 加 1。 陣列可以存放各種物件,包含自訂的物件。 38/38