$30 off During Our Annual Pro Sale. View Details »

認識 JavaScript : 與其它程式語言的異同

認識 JavaScript : 與其它程式語言的異同

2011 微軟開發者日

Ping-Yen Tsai

June 21, 2011
Tweet

More Decks by Ping-Yen Tsai

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. 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 ?

    View Slide

  5. Regular Expression Literal
    var r1 = new RegExp('JavaScript');
    var r2 = new RegExp('JavaScript', 'gi');
    var r1 = /JavaScript/;
    var r2 = /JavaScript/gi;

    意義相同

    View Slide

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

    View Slide

  7. 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 ⾃自動轉型

    View Slide

  8. 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

    View Slide

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

    View Slide

  10. 物件好像 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];

    View Slide

  11. 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; }

    View Slide

  12. 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);
    }

    View Slide

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

    View Slide

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

    View Slide

  15. 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

    View Slide

  16. self executing anonymous function

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

    View Slide

  17. 匿名函式也可以遞迴
    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 只執⾏行⼀一次

    View Slide

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

    View Slide

  19. 函式中的 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

    View Slide

  20. ⽤用 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);
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  24. 裡⾯面的函式宣告和外⾯面函式⼀一樣的變數

    裡⾯面⽤用裡⾯面的 外⾯面⽤用外⾯面的
    function f() {
    var a = 1;
    g();
    alert(a); // 1
    function g() {
    alert(a); // undefined
    var a = 2;
    alert(a); // 2
    }
    }

    View Slide

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

    View Slide

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

    View Slide

  27. 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
    }
    }
    }
    裡⾯面的函式存取外⾯面函式的變數

    View Slide

  28. 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) { … }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 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) { … }

    View Slide

  35. 把 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] }

    View Slide

  36. 覆蓋 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] }

    View Slide

  37. 讓 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

    View Slide

  38. 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

    View Slide

  39. Q & A

    View Slide