a = 1; undefined > a 1 > alert(a); undefined > window Window 下⼀一⾏行顯⽰示的是什麼? 就好像在程式碼前加上 var x = 變成 var x = 1 + 1 然後把 x 的值顯⽰示在下⼀一⾏行 網址 about:blank 就是⼀一個 乾淨的 JavaScript 環境
undefined 不⼀一樣 • not defined 是 JavaScript 錯誤 var a; alert(a); // undefined var b = null; alert(b); // null b = undefined; alert(b); // undefined alert(c); // ReferenceError: c is not defined
Function 也是 Object • Object 最⼤大特性 可以有屬性 • Primitive type 不可以有屬性 var a = 1; a.b = 2; alert(a.b); // undefined var a = new Object(); a.b = 2; alert(a.b); // 2 沒有錯誤訊息 但寫不進去
o = new Object(); alert(o.p); // undefined o.p = 1; alert(o.p); // 1 delete o.p; alert(o.p); // undefined alert(a); // ReferenceError: a is not defined
value Copy Compare Pass • string 也是依 value var o = new Object(), o2 = o; alert(o.p); // undefined; o2.p = 1; alert(o.p); // 1 var o = new Object(); f(o); alert(o.p); // 1 function f(o) { o.p = 1; } var a = 1; f(a); // Pass by value alert(a); // 1 function f(a) { a += 2; } var str = 'abc', str2 = 'abc'; alert(str === str2); // true
學 Object 實字 var o = new Object(); var o2 = new Object(); o2.p = 1; o2.q = 'abc'; var o3 = new Object(); o3['…'] = true; var o = {}; var o2 = { p : 1, q : 'abc' }; var o3 = { '…' : true }; 左右兩邊意義相同
例 Java 、 C 、 C# … • Dynamic type • 變數型態可以改變 • 例 JavaScript 、 PHP … • JavaScript ⽤用中性詞 var 宣告變數 • JavaScript 物件屬性同變數 int v = 1; v = "abc"; error var v = 1; v = 'abc'; v = function() { alert('f'); } v(); // f
JavaScript error 程式執⾏行中斷 if(a) // ReferenceError: a is not defined alert(a); JavaScript error 程式執⾏行中斷 if(typeof a !== 'undefined') alert(a); not defined 的資料型態是 undefined
• Weak typing 相反是 Strong typing • 例 Java 、 C 、 C# … var str = 'abc'; alert(str.charAt(1)); // b ⾃自動轉型 str -> new String(str) (new String(str)).charAt(1) string -> String number -> Number boolean -> Boolean var n = 1; n.toString(); int n = 1; (new Integer(n)).toString(); Java vs. JavaScript
結果常是 NaN alert(1 - 'A'); // NaN alert(typeof NaN); // number alert(NaN === NaN); // false alert(isNaN(NaN)); // true 和 NaN 做數字運算 結果恆 NaN NaN 是⼀一個數字 NaN 不等於任何東⻄西 請⽤用 isNaN( ) 判斷是不是 NaN
左右兩邊意義相同 var arr = new Array(); var arr2 = new Array('abc', 1, true); var arr = []; var arr2 = ['abc', 1, true]; var arr = [100]; alert(arr.length); // 1 alert(arr[0]); // 100 沒有傳⼊入⼀一個參數問題
JavaScript • RegExp 實字 • 檔案較⼩小 效能較佳 • JSON 沒有學 RegExp 實字 左右兩邊意義相同 var re = new RegExp('CHT'); var re2 = new RegExp('CHT', 'g'); var re3 = new RegExp('CHT', 'gi'); var re = /CHT/; var re2 = /CHT/g; var re3 = /CHT/gi;
Function Reference 丟出 alert(f(1, 2)); // 3 function f(x, y) { return x + y; } var f = function(x, y) { return x + y; } alert(f(1, 2)); // 3 alert(f(1, 2)); // ReferenceError: f is not defined var f = function(x, y) { return x + y; } 等於在 excution context 的最上⽅方寫 var f = function(x, y) { return x + y; }
• IE9 與 IE9 以下有 bug var f = function(x, y) { return x + y; } var f = function g () { alert(typeof f); // function alert(typeof g); // function } alert(typeof f); // function alert(typeof g); // undefined f(); IE9 與 IE9 以下會跳 function
alert(this.p); } var a = { p : 1, m : f }, b = { p : 2, m : f }; f.call(a); // 1 f.apply(a); // 1 a.m.call(b); // 2 a.m.apply(b); // 2 第⼀一個參數指定函式中 this
• 傳⼊入參數個數不定 • 利⽤用 square() sum() 搭配 apply() • 計算傳⼊入參數個別平⽅方後總合 function square() { var n = arguments.length; for(var i = 0; i < n; ++i) arguments[i] *= arguments[i]; return arguments; } 把傳⼊入參數都平⽅方 function sum() { var sum = 0, n = arguments.length; for(var i = 0; i < n; ++i) sum += arguments[i]; return sum; } 把傳⼊入參數加總
function g() { alert(1); } } f(); function f() { var g = function() { alert(1); } g(); // 1 } f(); function f() { g(); // ReferenceError: g is not defined var g = function() { alert(1); } } 等於在 excution context 的最上⽅方寫 var g = function() { alert(1); }
f() { var c = 0; function g() { ++c; } } 函式 g ⽣生存期間與函式 f 執⾏行期間⼀一樣 var h = f(); function f() { var c = 0; function g() { ++c; } return g; } 函式 g ⽣生存期間與函式 f 執⾏行期間不⼀一樣 變數 c 和函式 g ⽣生存期間綁⼀一起
// 1 h1(); // 2 h2(); // 1 function f() { var c = 0; function g() { alert(++c); } return g; } 函式 f 第⼀一次執⾏行 產⽣生了第⼀一份變數 c 、函式 g 與 Closure 第⼀一份函式 g 被回傳給 h1 函式 f 第⼆二次執⾏行 產⽣生了第⼆二份變數 c 、函式 g 與 Closure 第⼆二份函式 g 被回傳給 h2 第⼀一份變數 c 、函式 g 與 Closure 第⼆二份變數 c 、函式 g 與 Closure 是完全分開、各⾃自獨⽴立的
影響效能 • 宣告變數 記得寫 var var a = 1; f(); function f() { var b = 2; g(); function g() { var c = 3; h(); function h() { var d = 4; alert(d); // 4 alert(c); // 3 alert(b); // 2 alert(a); // 1 } } }
JavaScript ⺫⽬目前還不⽀支援 Class 繼承 • Google Maps JavaScript API v3 範例 • Using closures in event listeners • Vexed's Blog 搜尋 Closure • http://blog.xuite.net/vexed
下 this 為 undefined 外 • 沒寫 new 不會有錯誤訊息 function Cat(name) { this.name = name; } var cat1 = Cat('kitty'); alert(cat1); // undefined alert(name); // kitty ECMAScript 5 Strict Mode 外 this 是 Global 物件 Global 物件的屬性就是 Global 變數 所以變成設定 Global 變數 name