1. 程式人生 > 其它 >ECMAScript -- let 和塊級作用域

ECMAScript -- let 和塊級作用域

什麼是塊級作用域?js中有塊級作用域嗎?

  • 塊級作用域,指程式碼中用{}括起來的範圍,如下程式碼所示:
// if語句
if(true){
  console.log('block')
}
// for語句
for(var i =0;i<10;i++){
  consolo.log(i)
}
  • 在es2015之前,是沒有塊級作用域的概念的,即塊是沒有其獨立的作用域的,導致在塊中定義的成員可以被外部訪問
if(true){
  var a='aaa'
}
console.log(a)
// 輸出:
// aaa

像上面這樣的情況,在程式碼量大的情況是很不安全的,也很難維護

  • 在es2015後,出現了let 關鍵字,用let宣告的變數是隻能在其被宣告時的程式碼塊中被訪問
if(true){
  let a ='aaa'
  console.log('塊中的a:'+a)
}
console.log(a)// 會報錯,a is not defined

let 的作用

  • 適用於宣告for迴圈中的記數器

es2015前,巢狀的for迴圈必需要為每層迴圈設定不同的記數器名稱,不然會出現意料之外的情況

for(var i=0;i<3;i++){
  for(var i=0;i<3;i++){
    console.log(i)
  }
}
// 輸出:
// 0
// 1
// 2

很顯示,我們認為的是會輸出9次結果,然而並不是,因為兩層迴圈使用相同的i,並且不是使用var定義,即沒有塊級作用域,那麼內層迴圈的i會覆蓋外層迴圈的i,導致當內層迴圈完成時,i變成3了,外層迴圈的i也是3,將不滿足迴圈條件而直接結束迴圈

es2015後,使用let關鍵字使得巢狀的for迴圈可以為每層迴圈設定相同的記數器名稱

for(let i=0;i<3;i++){
  for(let i=0;i<3;i++){
    console.log(i)
  }
}
// 輸出:
// 0
// 1
// 0
// 1
// 2
// 0
// 1
// 2 

因為使用let產生了塊級作用域,內層迴圈不會影響外層迴圈,但是平時開發中還是不建議使用同名的記數器,同名計數器不利於我們後期去理解程式碼,造成維護困難

let 沒有變數提升

在es2015之前 ,var 定義變數可以在使用之後,因為預設的var 變數的定義會被提升到作用域前部,而使用let後,在使用後再定義變數會報錯

console.log(foo) //輸出undefined, 定義被提升,但是賦值不會提升
var foo='abc'

console.log(foo) //會報錯,因為foo在此前未定義
let foo='abc'