1. 程式人生 > >JavaScript ES6 的let和const

JavaScript ES6 的let和const

str ava gre 而已 sting 全局 tom turn 賦值

1 作用域和提升

1.1 作用域(Scope)

某個變量名或者函數名,在某個程序片段中是否可見或者可訪問,如果是,那麽這個程序片段就是這個變量名或者函數名的作用域。比如:

 1 var name = "Tom";
 2 function getInlibrary(){
 3   var libraryName = "Xinhua";
 4   console.log(name );      
 5   console.log(libraryName );
 6 }
 7 
 8 getInlibrary();
 9 console.log(name ); 
10 console.log(libraryName );

輸出結果:

Tom
Xinhua
Tom
Uncaught ReferenceError: libraryName is not defined

變量name的作用域是全局,變量libraryName的作用域是函數getInlibrary。使用var來聲明變量,作用域要麽是全局,要麽是函數。

1.2 提升(Hoisting)

先看一段代碼:

1 console.log(findAverage(3,5));
2 function findAverage(a,b){
3   return (a + b)/2.0;  
4 }

控制臺將會打印什麽結果?undefined?因為打印語句在聲明函數之前就執行了。然而答案是,控制臺將輸入正確的結果:4.

  這樣先調用函數,後聲明函數是可行的!因為JavaScript的提升機制會在代碼執行前,將所有函數聲明或變量聲明提升到它們的作用域頂部,而初始化語句不會被提升

要註意“它們的作用域”,例如如下代碼:

  提升前

1 function greeting(){
2    console.log(hello);
3    var hello =  "hello!";   
4 }
5 greeing();

  提升後

1 function greeing(){
2   var hello;
3   console.log(hello);
4   hello = "hello!";     
5 } 6 greeting();

因此,從提升後的代碼就可以看出,程序輸出結果是undefined了。

2 let和const 代替 var聲明變量

2.1 為什麽要引入let和const

  先看一段代碼:

1 function varTest() {
2   var x = 1;
3   if (true) {
4     var x = 2;  // same variable!
5     console.log(x); 
6   }
7   console.log(x); 
8 }
9 varTest();

輸入結果:
2
2

上面代碼的輸出結果,為什麽會出現上面的輸出結果?看一下提升後的代碼:

1 function varTest() {
2   var x;
3   var x = 1;
4   if (true) {
5     x = 2;  // 重新賦值
6     console.log(x);  // 2
7   }
8   console.log(x);  // 2
9 }

從提升後的代碼可以看出來,變量x的聲明被提升到了函數的頂部,在第3行中被賦值為1,在第5行被重新賦值為了2,因此後面輸出都是2.

以上結果顯然並不是我們想要的,造成這個結果的原因就是因為ES6之前,JavaScript變量的作用域只有全局和函數兩種作用域而已,而缺少塊級域,所謂“塊”,就是花括號"{}"括起來的部分。

因此ES6引用了let和const,它們與var的區別就在於其作用域延伸了一個:塊。將上述代碼"var"改為"let"後:

 1 function letTest() {
 2   let x = 1;    //聲明了一個變量x, 作用域是letTest函數
 3   if (true) {
 4     let x = 2;  //聲明了一個變量x, 作用域是if塊
 5     console.log(x);   //2
 6   }
 7   console.log(x);  //1
 8 }
 9 
10 letTest();

輸出結果:
2
1

以上結果符合了我們的預期!大家仔細體會“另一個變量x”。

2.2 const 、let與var的區別

  const、let與var區別是:

    let可以重新賦值,不能在同一個作用域重復聲明,其聲明的變量的作用域為全局、函數或者塊。

    const不能重新賦值,不能在同一個作用域重復聲明,其聲明的變量的作用域為全局、函數或者塊。

    var可以重新賦值,可以在同一個作用域重復聲明,其聲明的變量的作用域為全局或者函數。

那麽,var還有用麽?沒用了!建議盡可能不要使用var來聲明變量了,如果你不需要改變變量值,就用const,如果需要改變變量的值,就用let.

JavaScript ES6 的let和const