JavaScript 是需要被瞭解
JavaScript 是一種非常方便就能上手及使用的程式語言,但真正瞭解 JavaScript 就不多了。借由 HTML5 的推助,JavaScript 再一次站上主角,第一次是 XMLHttpRequest 的 AJAX 應用,而 HTML5 滿滿的 API 全部都必須使用 JavaScript 撰寫來實現。我們必須更進一瞭解 JavaScript,而不只是簡單帶過。
這一篇會介紹 JavaScript 裡一些小知識,包含物件,數字,字串,陣列,迴圈等。
萬物皆物件
在 JavaScript 的世界裡,除了非常少數核心部分,廣義而言,可以說萬物階物件(Object),我們常看和不常看的型態都是一種物件,例如:
- Number (數字是物件)
- String (字串是物件)
- Boolean (布林是物件)
- Object (物件是物件)
- Function (函式是物件)
- Array (陣列是物件)
- Date (日期是物件)
- regExp (正規表達式是物件)
- Null (空是物件)
- Undefined (未定義是物件)
- Error (錯誤是物件)
好多物件,這和我們學習的正規程式語言有很大差異,但沒關係,當你在學習 JavaScript 時,如果有卡卡的,看不懂的地方,回想這句話:「萬物階物件」,用物件的角度來看事情,先不要管它是個什麼東西,它就物件,很多時候問題會簡單很多。
數字小知識
第一件事,在 JavaScript 中沒有整數這件事。在規範中 JavaScript 數字是一個「雙精確度 64位元格式 IEEE745 值(double-precision 64-bit binary format IEEE 754 value)」,所以在做小數點及大數運算時必須小心。例如,「0.1 + 0.2」或「一個 16位數或超過 16位數」的數值。
第二件事,在進行 parseInt() 函式將字串轉成整數時,一定要指定第二個參數,第二個參數指定進位數。
04 | var b = 9999999999999998; |
07 | var c = 9999999999999999; |
10 | var d = parseInt( "014" ); |
13 | var e = parseInt( "014" , 10); |
16 | var f = parseInt( "014" , 16); |
以上程式碼純屬程式,沒有其他用意。@_@
字串小知識
JavaScript 裡的每個字元都會序列化為 Unicode字元,即會以一個 16位元的字數來表示。這可以讓需要國際化的不用特別擔心編碼問題。你寫什麼(中文、韓文、日文、印度文…),網頁裡就是顯示什麼。
1 | document.writeln( "我愛妳" ); |
2 | document.writeln( "我爱妳" ); |
3 | document.writeln( "私はあなたを愛して" ); |
null 與 undefined 小知識
null(空),是一種無數值的情況。undefined(未定義),是一種未初始化的情況。
a 是未定義;b 是空。你宣告一個變數但未指定值,那是未定義不是空。空是一種狀態。我們常在 for 迴圈內使用 return 來跳離迴圈,return 未指定值,那是未定義不是空。
&& 與 || 小知識
&& (and) 與 || (or) 運算子在判斷條件時,第二個條件是否執行依第一個條件來決定。這用來存取一個物件的屬性前檢查物件是否為空非常有用。
02 | var event = window || window.event; |
06 | var name = person && person.getName(); |
10 | var englishName = person || "無" ; |
物件小知識
JavaScript 裡的物件是字典(name-value pair),name 的部分必須是字串, value 可以是任何 JavaScript 的值。JavaScript 的值就是好玩的地方,因為可放任何 JavaScript 的值,所以物件裡可以放物件,還記得第一點嗎,萬物皆物件,到了這裡可以再加一句,萬物皆可放。
03 | var objA = new Object(); |
07 | objB.boyName = "Bruce" ; |
08 | var manName = objB.boyName; |
10 | objB[ "girlName" ] = "Sherry" ; |
11 | var womanName = objB[ "girlName" ]; |
第二種用法有個優點,屬性的名稱是以字串提供,當你將屬性設定為 JavaScript 關鍵字時,第二種存取方法不會出錯,第一種 . (點)物件存取是不可以使用 JavaScript 關鍵字。
13 | var foodColor = food.details.color; |
name,"for" 是屬性,for 是關鍵字,用 "for" 表示它是單純字串,details 是個物件,color,price 是屬性。實務上,我們會把物件屬性名稱都用字串表示,這在未來撰寫 JSON 相關應用時,可以用一致的習慣來撰寫,這裡是為了展示物件範例才未加上。
陣列小知識
陣列的運作和物件很像。
{} 與 [] 都是實體語法,實務上我們也大多使用實體語法是撰寫 JavaScript 程式碼。陣列好玩的地方在它有個物件沒有的屬性 length (長度)。
2 | var arrC = [ "Dog" , "Cat" , "Fish" , "Bird" ]; |
3 | console.log(arrC.length); |
5 | var arrD = [ "Dog" , "Cat" , "Fish" , "Bird" ]; |
第二範例的 arrD 讓我們瞭解二件事,一是 JavaScript 的陣列隨時可變,而且會自動調整至 index 指定的大小。二是 length 的回傳值是最高 Index 值加一。JavaScript 的索引是由 0 開始,length 是回傳項目個數,它不管項目是否有值。如果我們查取一個不存在的陣列,得到會是未定義(undefined),說到這裡是否瞭解 null 和 undefinded 差異了。
1 | console.log( typeof (arrD[33])); |
前面我們瞭解到 length 的回傳值是最高 Index 值加一,利用此特性,我們可以在陣列的最尾端加入項目:
1 | arrD[arrD.length] = "Ant" ; |
這可以說是最安全有順序加入陣列的方式。
陣列迴圈處理小知識
我們經常使用迴圈來取陣列的值。
1 | for ( var i=0; i < arrD.length; i++){ |
注意這裡「i < arrD.length」,程式每判斷一次就必須去取出 arrD.length 一次,這不是很呆嗎?應該這樣做:
1 | for ( var i=0, len=arrD.length; i<len ; i++){ |
我們先取出 arrD.length 的值讓它成為 len 變數,接下來只要拿 len 來進行判斷,程式馬上加速。另外還可以再加以變型:
1 | for ( var i=0, value; value = arrD[i]; i++){ |
這是利用 for 迴圈執行前會先測試條件( value = arrD[i] )是否為真,成功,便執行迴圈。執行順序為:
- 初始變數
- 測試 arrD[i] 是否有值
- arrD[i] 有值,進行取值及設定給變數 value,執行 for 迴圈
- arrD[i] 無值,離開 for 迴圈
第二步是重點,它的使用比第二種 len=arrD.length 更直接也更快,第二種方式因是必須在 for 迴圈內再進行一次取值處理的動作。不過此技巧有個小限制,你必須非常確定陣列裡不會有「假值」,例如,可能含有數字 0、空字串、陣列裡的物件、DOM 節點 … 有的話,還是使用第二種來處理。
If the string begins with "0", the radix is 8 (octal). This feature of parseInt() functionis deprecated
回覆刪除