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() 函式將字串轉成整數時,一定要指定第二個參數,第二個參數指定進位數。
var a = 0.1 + 0.2; document.writeln(a); // 0.30000000000000004 var b = 9999999999999998; document.writeln(b); var c = 9999999999999999; document.writeln(c); // 10000000000000000 var d = parseInt("014"); document.writeln(d); // 12,果然有問題 var e = parseInt("014", 10); document.writeln(e); // 14,你在貪污呀,抓到了吧 var f = parseInt("014", 16); document.writeln(f); // 20,這是洗錢手法之一
以上程式碼純屬程式,沒有其他用意。@_@
字串小知識
JavaScript 裡的每個字元都會序列化為 Unicode字元,即會以一個 16位元的字數來表示。這可以讓需要國際化的不用特別擔心編碼問題。你寫什麼(中文、韓文、日文、印度文…),網頁裡就是顯示什麼。
document.writeln("我愛妳"); document.writeln("我爱妳"); document.writeln("私はあなたを愛して");
null 與 undefined 小知識
null(空),是一種無數值的情況。undefined(未定義),是一種未初始化的情況。
var a; // undefined var b = null; // null
a 是未定義;b 是空。你宣告一個變數但未指定值,那是未定義不是空。空是一種狀態。我們常在 for 迴圈內使用 return 來跳離迴圈,return 未指定值,那是未定義不是空。
&& 與 || 小知識
&& (and) 與 || (or) 運算子在判斷條件時,第二個條件是否執行依第一個條件來決定。這用來存取一個物件的屬性前檢查物件是否為空非常有用。
// 跨瀏覽器處理 var event = window || window.event; // 1. person 物件不為 null // 2. 取出 person.getName() 的值 var name = person && person.getName(); // 1. person 物件為 null // 2. 指定 "無" 為預設值 var englishName = person || "無";
物件小知識
JavaScript 裡的物件是字典(name-value pair),name 的部分必須是字串, value 可以是任何 JavaScript 的值。JavaScript 的值就是好玩的地方,因為可放任何 JavaScript 的值,所以物件裡可以放物件,還記得第一點嗎,萬物皆物件,到了這裡可以再加一句,萬物皆可放。
// 意義上,objA 與 objB 是相等,都是產生一個空物件。 // 實務上都會使用實體語法,尤其是在物件及陣列 var objA = new Object(); var objB = {}; // 實體語法(object literal) // 意義上,兩種存取語法是相同的 objB.boyName = "Bruce"; // 存 var manName = objB.boyName; // 取 objB["girlName"] = "Sherry"; // 存 var womanName = objB["girlName"]; // 取
第二種用法有個優點,屬性的名稱是以字串提供,當你將屬性設定為 JavaScript 關鍵字時,第二種存取方法不會出錯,第一種 . (點)物件存取是不可以使用 JavaScript 關鍵字。
// 直接進行屬性初始化 // 格式 name : value var food = { name: "紅蘿蔔", "for": "Happy", details: { // 物件裡的物件 color : "red", price : 23, } }; // 一層一層存取即可 var foodColor = food.details.color;
name,"for" 是屬性,for 是關鍵字,用 "for" 表示它是單純字串,details 是個物件,color,price 是屬性。實務上,我們會把物件屬性名稱都用字串表示,這在未來撰寫 JSON 相關應用時,可以用一致的習慣來撰寫,這裡是為了展示物件範例才未加上。
陣列小知識
陣列的運作和物件很像。
var arrA = new Array(); var arrB = []; // 實體語法
{} 與 [] 都是實體語法,實務上我們也大多使用實體語法是撰寫 JavaScript 程式碼。陣列好玩的地方在它有個物件沒有的屬性 length (長度)。
// 直接進行陣列初始化 var arrC = ["Dog", "Cat", "Fish", "Bird"]; console.log(arrC.length); // 4 var arrD = ["Dog", "Cat", "Fish", "Bird"]; arrD[14] = "Money"; // 14 說給我錢,其他免談 arrD.length; // 15
第二範例的 arrD 讓我們瞭解二件事,一是 JavaScript 的陣列隨時可變,而且會自動調整至 index 指定的大小。二是 length 的回傳值是最高 Index 值加一。JavaScript 的索引是由 0 開始,length 是回傳項目個數,它不管項目是否有值。如果我們查取一個不存在的陣列,得到會是未定義(undefined),說到這裡是否瞭解 null 和 undefinded 差異了。
console.log(typeof(arrD[33])); // undefined
前面我們瞭解到 length 的回傳值是最高 Index 值加一,利用此特性,我們可以在陣列的最尾端加入項目:
arrD[arrD.length] = "Ant"; // 相等 arrD.push("Ant");
這可以說是最安全有順序加入陣列的方式。
陣列迴圈處理小知識
我們經常使用迴圈來取陣列的值。
for (var i=0; i < arrD.length; i++){ // Do something }
注意這裡「i < arrD.length」,程式每判斷一次就必須去取出 arrD.length 一次,這不是很呆嗎?應該這樣做:
for (var i=0, len=arrD.length; i<len ; i++){ // Do something }
我們先取出 arrD.length 的值讓它成為 len 變數,接下來只要拿 len 來進行判斷,程式馬上加速。另外還可以再加以變型:
for (var i=0, value; value = arrD[i]; i++){ // Do something }
這是利用 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
回覆刪除