Slide 1

Slide 1 text

認識 JavaScript : 與其它程式語⾔言的異同 Vexed 蔡秉諺

Slide 2

Slide 2 text

個⼈人簡歷 • 中正⼤大學電⼦子計算機中⼼心 • 中正資⼯工 GAIS Lab • 新典資訊 • 中華電信數據通信分公司網際內容處三科

Slide 3

Slide 3 text

Why me? • HTML5 • Core JavaScript Client-side JavaScript Core JavaScript Server-side JavaScript Core JavaScript JScript .NET Core JavaScript

Slide 4

Slide 4 text

Literal 實字 var o1 = new Object(); var o2 = new Object(); o2.p = 1; o2.q = 2; var a1 = new Array(); var a2 = new Array(); a2[0] = 1; a2[1] = 2; var o1 = {}; var o2 = { p : 1, q : 2 }; var a1 = []; var a2 = [1, 2]; ← 意義相同 → JSON ?

Slide 5

Slide 5 text

Regular Expression Literal var r1 = new RegExp('JavaScript'); var r2 = new RegExp('JavaScript', 'gi'); var r1 = /JavaScript/; var r2 = /JavaScript/gi; ↑ 意義相同 ↓

Slide 6

Slide 6 text

JavaScript is • weak typing ⾃自動轉型 • dynamic typing • 執⾏行期間增改刪屬性 var o = {}; o.p = 1 + '2'; // '12' o.p = function(){ alert('f'); } o.p(); // f delete o.p;

Slide 7

Slide 7 text

Data Type • Primitive Type – number (值 float, 沒有型態 int) – string (沒有型態 char) – boolean – null – undefined • Object – Array – Function … string -> String number -> Number boolean -> Boolean var s = 'ABCDE'; alert(s.substr(1, 2)); // BC weak typing ⾃自動轉型

Slide 8

Slide 8 text

Operator • ⼤大致和其他語⾔言相同 • weak typing == != 轉型後⽐比對 === !== 型態也需相同⽐比對 • && || 不是回傳 true false 回傳確⽴立結果時的運算元 var a = 1 && 's'; // 's' var b = null && 1; // null var c = 1 || 's'; // 1 var d = null || 0; // 0

Slide 9

Slide 9 text

物件屬性存取⽅方式 • . 和 [] o.p ←意義相同→ o['p'] • 屬性名稱可以包含 任意字元 o['~!@#$%^&*(.'] var s = 'p'; var a = o[s]; var b = eval('o.' + s); var o = { '~!@#$%^&*.' : 1 }; Object Literal

Slide 10

Slide 10 text

物件好像 C# Dictionary, Java Map var o = {}; var key = 'k', value = 'v'; o[key] = value; if(o[key]) alert(o[key]); // v for(var i in o) { alert(i); // k alert(o[i]); // v } delete o[key];

Slide 11

Slide 11 text

Function 是物件 var f1 = new Function('x', 'y', 'return x + y'); var a = f2(1, 1); // js error, f2 is not a function var f2 = function(x, y) { return x + y; } var b = f2(1, 1); // 2 var c = f3(1, 1); // 2 function f3(x, y) { return x + y; }

Slide 12

Slide 12 text

Function 參數個數不受限 f(1) // 1, undefined, undefined f(1, 2, 3, 4) // 1, 2, 3 function f(a, b, c) { alert(a); alert(b); alert(c); }

Slide 13

Slide 13 text

arguments 存取參數 f(1, 2, 3, 4); function f() { var x = arguments.length; // 4 var y = arguments[2]; // 3 }

Slide 14

Slide 14 text

給予 Function 參數初始值 function f(a, b, c) { a = a || 1; b = b || 2; c = c || 3; }

Slide 15

Slide 15 text

Anonymous function 匿名函式 var a = [1, 3, 2, 5, 4]; function compare(a, b){ return a - b; } a.sort(compare); alert(a); // 1,2,3,4,5 var a = [1, 3, 2, 5, 4]; a.sort(function(a, b) { return a - b; }); alert(a); // 1,2,3,4,5

Slide 16

Slide 16 text

self executing anonymous function
 ⾃自⼰己執⾏行的匿名函式 (function() { /* 乾淨的變數空間 */ var a = 1; })(); alert(a); // js error, a is not defined

Slide 17

Slide 17 text

匿名函式也可以遞迴 var m = (function(n) { // factorial if(n <= 1) return 1; return n * arguments.callee(n - 1); })(3); oDiv.addEventListener('click', function() { oDiv.removeEventListener('click', arguments.callee); // ... }); Event 只執⾏行⼀一次

Slide 18

Slide 18 text

函式中宣告變數沒寫 var 會是全域變數 (function() { var a = 1; })(); alert(a); // js error, a is not defined (function() { a = 1; })(); alert(a); // 1

Slide 19

Slide 19 text

函式中的 this function f() { alert(this.p); } var a = { p : 1, m : f }, b = { p : 2, m : f }; a.m(); // 1 b.m(); // 2 f(); // undefined

Slide 20

Slide 20 text

⽤用 call, apply 指定 this function f() { alert(this.p); } var a = { p : 1, m : f }, b = { p : 2, m : f }; a.m.call(b); // 2 f.call(b); // 2 a.m.call(b, 3, 4); a.m.apply(b, [3, 4]); function g() { a.m.apply(b, arguments); }

Slide 21

Slide 21 text

沒指定, this 就是 Global Object function f() { alert(this.p); } f(); // undefined var p = 1; f(); // 1 Global 變數 就是 Global Object 的屬性

Slide 22

Slide 22 text

函式裡⾯面可以再寫函式 function f() { g(); // 1 function g() { alert(1); } } g(); // js error: g is not defined 裡⾯面的函式 global 看不⾒見

Slide 23

Slide 23 text

裡⾯面的函式可以存取外⾯面函式的變數 function f() { var a = 1; g(); alert(a); // 2 g(); alert(a); // 3 function g() { ++a; } }

Slide 24

Slide 24 text

裡⾯面的函式宣告和外⾯面函式⼀一樣的變數
 裡⾯面⽤用裡⾯面的 外⾯面⽤用外⾯面的 function f() { var a = 1; g(); alert(a); // 1 function g() { alert(a); // undefined var a = 2; alert(a); // 2 } }

Slide 25

Slide 25 text

Closure = 函式 + 外⾯面的變數 function f() { var a = 1; function g() { ++a; } } var h = f(); function f() { var a = 1; function g() { ++a; } return g; }

Slide 26

Slide 26 text

Closure 匿名函式化 var h = (function() { var a = 1; return function() { ++a; } })(); var h = (function() { var count = 0; return function() { ++count; // 計算 h 的執⾏行次數 } })();

Slide 27

Slide 27 text

Scope chain var a = 1; 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 } } } 裡⾯面的函式存取外⾯面函式的變數

Slide 28

Slide 28 text

Constructor function Cat(name) { this.name = name; } var cat1 = new Cat('kitty'), cat2 = new Cat('lucky'); alert(cat1.name); // 'kitty' alert(cat2.name); // 'lucky' alert(cat1 instanceof Cat); // true alert(cat1.constructor); // function Cat(name) { … }

Slide 29

Slide 29 text

函式就是 Constructor function Cat(name) { this.name = name; } var cat1 = new Cat('kitty'); 關鍵在有沒有 new

Slide 30

Slide 30 text

記得寫 new function Cat(name) { this.name = name; } var cat1 = Cat('kitty'); alert(cat1); // undefined alert(name); // kitty /* 沒有錯誤 */

Slide 31

Slide 31 text

Prototype • Constructor 的⼀一個屬性 預設是空物件 {} • instance 沒有的屬性會到 Constructor.prototype 找 • 所有這個 Constructor new 出來的 instance 共⽤用 ! ?

Slide 32

Slide 32 text

Prototype範例 function Cat(name) { this.name = name; } Cat.prototype.meow = function() { alert('meow'); } var cat1 = new Cat('kitty'), cat2 = new Cat('lucky'); cat1.meow(); // meow cat2.meow(); // meow cat1.meow = function() { alert('bark'); } cat1.meow(); // bark cat2.meow(); // meow

Slide 33

Slide 33 text

hasOwnProperty
 檢查是⾃自⼰己的屬性 還是 prototype 的 function Cat(name) { this.name = name; } Cat.prototype.meow = function() { alert('meow'); } var cat1 = new Cat('kitty'); alert(cat1.hasOwnProperty(name)); // true alert(cat1.hasOwnProperty(meow)); // false

Slide 34

Slide 34 text

constructor 屬性是在 prototype 上 function Cat(name) { this.name = name; } var cat1 = new Cat('kitty'); alert(cat1.constructor); // function Cat(name) { … } alert(cat1.hasOwnProperty('constructor')); // false alert(Cat.prototype.constructor); // function Cat(name) { … }

Slide 35

Slide 35 text

把 prototype 覆蓋掉 function Cat(name) { this.name = name; } Cat.prototype = { age : 1, gender : 'female' } var cat1 = new Cat('kitty'); alert(cat1.constructor); // function Object() { [native code] } alert(Cat.prototype.constructor); // function Object() { [native code] }

Slide 36

Slide 36 text

覆蓋 prototype 多寫屬性 constructor function Cat(name) { this.name = name; } Cat.prototype = { age : 1, gender : 'female', constructor : Cat } var cat1 = new Cat('kitty'); alert(cat1.constructor); // function Cat() { [native code] }

Slide 37

Slide 37 text

讓 prototype 是另⼀一個物件 instance function Animal() { } Animal.prototype.energy = 100; function Cat(name) { this.name = name; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat1 = new Cat('kitty'); alert(cat1.energy); // 100 cat1 ↓ Cat.prototype ↓ Animal.prototype ↓ Object.prototype Object.prototype.everyone = 'Yes'; alert(cat1.everyone); // Yes Prototype chain alert(cat1 instanceof Cat); // true alert(cat1 instanceof Animal); // true alert(cat1 instanceof Object); // true alert(cat1 instanceof Array); // false

Slide 38

Slide 38 text

instance 參照的 prototype
 在 new 時就綁定 function Cat(name) { this.name = name; } Cat.prototype.age = 10; var cat1 = new Cat('kitty'); alert(cat1.age); // 10 alert(cat1 instanceof Cat); // true Cat.prototype = { age : 20, constructor : Cat }; alert(cat1.age); // 10 var cat2 = new Cat('lucky'); alert(cat1 instanceof Cat); // false alert(cat2 instanceof Cat); // true

Slide 39

Slide 39 text

Q & A