iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 27

[Day 27] JavaScript ES6 語法- 變數範圍鏈、常數、函式範圍鏈

  • 分享至 

  • xImage
  •  

變數範圍鏈 (Variable Scoping)

let 與 var 的不同在於變數有效範圍界定的差別。 var 是 function 界定變數的有效範圍,而 let 則是以區塊界定有效範圍,如 if () { 作用範圍 }、 for () { 作用範圍 } 等等。

下方我們就用一些程式碼來說明其差別與先前提到的死區 ( Dead Zone )吧!


    //es5
    
     (function() {
         var a = 5;
         (function() {
             var a = 6;
             console.log(a); // 6
         })();
         console.log(a); // 5
     })();

     //es6
     
     {
         let a = 5;
         {
             let a = 6;
             console.log(a); // 6
         }
         console.log(a); // 5
     }
     
     //let在for迴圈中
     
     for (let i = 0; i < 5; i++) {
         setTimeout(function() {
             console.log(i); // 分別 0, 1, 2, 3, 4, 5
         }, i * 1000);
     }
     
     //let看起來好像沒有hoisting
     
     {
         console.log(a);
         let a = 1;
     }
     
     //let 其實有 hoisting 但無法操作(又稱死區Dead Zone)
     
     {
         let a = 2;
         {
             console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
             let a = 1;
         }
     }


常數 (Constants)

JavaScript 中並沒有常數的概念,大多數都是依照命名習慣,以全大寫表示一個常數,從 ES6 才開始加入 const 來定義常數。

const 定義的常數不可以重新指定值、不准許重複宣告、不准宣告前宣告前使用。


    //es5
    
     Object.defineProperty(typeof global === "object" ? global : window, "PI1", {
         value: 3.1415926,
         enumerable: true,
         writable: false,
         configurable: false
     });
     
     console.log(PI1); //3.1415926
     
     PI1 = 100;
     console.log(PI1); //3.1415926
     
     //es6
     
     const PI2 = 3.1415926;
     console.log(PI2); //3.1415926
     
     PI2 = 100; //Assignment to constant variable.
     console.log(PI2); //3.1415926

    
    //es5
    
     Object.defineProperty(typeof global === "object" ? global : window, "DATA1", {
         value: {
             content: "abc"
         },
         enumerable: true,
         writable: false,
         configurable: false
     });
     
     DATA1.content = "xyz";
     console.log(DATA1.content); // xyz
     
     //es6
     
     const DATA2 = {
         content: "abc"
     };
     DATA2.content = "xyz";
     
     console.log(DATA2.content); // xyz

涵式範圍鏈 ( Function Scoping )

在區塊內的 function 如同 let ㄧ樣。


    //es5
    
    (function() {
        function foo() { 
            return 1;
        }
        
        (function() {
            function foo() { 
                return 2;
            }
            console.log(foo()); // 2
        })();
        console.log(foo()); // 1
    })();
    
    //es6
    
    {
        function foo() { 
            return 1;
        }
        
        {
            function foo() { 
                return 2;
            }
            
            console.log(foo()); // 2
        }
        console.log(foo()); // 1
    }

ES6 採用 Block Level Function Declarations 界定 Function 範圍,由於 IE 8 ~ IE 10 不支援 ES6 ,仍然採用 hoisting 界定 function 範圍。


    if ( true ) {
        function foo() {
            return "a";
        }
    } else {
        function foo() {
            return "b";
        }
    }
    
    console.log(foo());


ES6 篇章開始了,後面希望多著墨在解構賦值的部分,寫著寫著也快結束了呢 : )

參考資料:

Tommy - 深入 JavaScript 核心課程

卡斯伯 - ES6 開始的新生活 let, const


上一篇
[Day 26] JavaScript 設計模式- 代理模式、中介者模式、觀察者模式
下一篇
[Day 28] JavaScript ES6 語法- 箭頭函式、函式參數擴展與字串樣板
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言