2017年8月20日 星期日

[JavaScript] ES5: Closure, Immediately Invoked Functions(IIFE)

  • ES 5 版本的規格,在 ES 6 可以使用 Let 來解決 Closure 的問題
  • Closure 
    • JavaScript function 可當一個值使用,因此 function 當回傳值是很普遍
    • JavaScript 變數的生命周期是存活在宣告 function  中,當 function 回傳值為 function  或者 object,而此 object 定義 function,這樣就形成 Closure,延長區域的變數生命周期
    • Case 1
    
    // 缺點 result 為全域變數
    var result = 0;
    
    function add (x, y) {
        result = (x + y);
        console.log(result);
    };
    
    add(10, 20);
    add(20, 30);
    add(30, 40);
    
    • Case 2
    
    // 使用 function 封裝,使 result 為區域變數
    function closureAdd() {
        var result = 0;
        
        function add (x, y) {
            result = (x + y);
            console.log(result);
        };
    
        add(10, 20);
        add(20, 30);
        add(30, 40);
    }
    
    closureAdd();
    
    • Case 3 - Closure
      • 使用巢狀式解決全域變數問題
      • 函數當值
    
    // 當函數的回傳值為 function,會形成 "Closure"
    // 延長區域變數的生命週期
    function closureAdd() {
        var result = 0;
        
        function add (x, y) {
            result = (x + y);
            console.log(result);
        };
    
        return add;
    }
    
    var add = closureAdd();
    
    add(10, 20);
    add(20, 30);
    add(30, 40);
    
    • Case 4 - Closure 簡化
    
    function closureAdd() {
        var result = 0;
    
        return function (x, y) {
            result = (x + y);
            console.log(result);
        };;
    }
    
    var add = closureAdd();
    
    add(10, 20);
    add(20, 30);
    add(30, 40);
    
  • Immediately Invoked Functions (IIFE)
    • 通常 function 都是被叫用後才執行 (ex: add())
    • IIFE 定義之後,馬上就會執行 function 
    • JavaScript 區域變數有效範圍 (Scope) 在 function 中,因變數宣告在 IIFE 中,可以避免區域變數命名與全域變數的名稱衝突問題
    • Case 5 - Closure, Immediately Invoked Functions
    
    var add = function () {
        var result = 0;
    
        return function (x, y) {
            result = (x + y);
            console.log(result);
        };;
    }();
    
    add(10, 20);
    add(20, 30);
    add(30, 40);
    

沒有留言:

張貼留言