從var 到 let,JS 用了整整18年!

查小小飛發表於2019-11-11

一個人的成功啊,不僅要靠個人的努力,還要考慮到歷史的程式。

18年?

看第一版的ECMA:1997年

從var 到 let,JS 用了整整18年!

看看支援let的版本:2015年

從var 到 let,JS 用了整整18年!

很難想象,只是一個語言特性的改版,竟然會用18年的時間,所以啊,一個人的成功,不僅要靠個人的努力,還要考慮到歷史的程式,對於一門語言同樣的適用。 很多人吐槽JS的很多缺陷,我覺得這不能怪 布蘭登·艾克,因為一開始,就沒想著JS能夠做多大的事兒,就是一門簡單的指令碼語言,能夠實現一些簡單功能就可以了。後來網際網路的日益繁榮,web的重視,才使得JavScript被委以重任,這也就要求JavaScript 變得越來越正式化,越來越是一門正真的程式語言。

從var說起

宣告前置

var 用於宣告一個變數,但是你需要注意到一些這種變數宣告的奇怪特性,就是 宣告前置

從var 到 let,JS 用了整整18年!

上面的程式碼中,第一行使用了變數 a,在c語言中,還沒宣告一個變數就使用,是會直接報錯的,但在JS中不會,而是會輸出 undefined 這就是宣告前置。上面的程式碼,相當於:

從var 到 let,JS 用了整整18年!

作用域

在ES6之前,你要知道,只有全域性作用域和函式作用域

在函式裡面宣告一個變數,在函式外部訪問會報錯:

從var 到 let,JS 用了整整18年!

如果像c語言一樣寫寫塊級作用域呢:

從var 到 let,JS 用了整整18年!

小結:var存在缺陷,宣告前置,作用域的問題,不像一個程式語言該有的變數宣告。

let的魔法

1. 暫時性死區

先使用,後定義會報錯,不會再像var 那樣隨意:

從var 到 let,JS 用了整整18年!

這是不是就說明了let 宣告的變數不會被前置呢?很多人認為let不會被提升,實際上不是這樣的,再看一個例子:

從var 到 let,JS 用了整整18年!
那麼究竟是怎麼回事呢?這就被稱為暫時性死區:就是指let宣告的變數必須先宣告並初始化成功後才能被引用,否則,這個變數就不能被引用,進入了暫存死區,就跟死了一樣。

2. 塊級作用域

從var 到 let,JS 用了整整18年!

不會再像 var一樣,let宣告的變數是有自己獨立的作用域的。

從var 到 let,JS 用了整整18年!

所以, let宣告的變數只在自己的程式碼塊中有效,即let宣告的變數就是區域性變數。

3. 重複宣告

重複宣告:

從var 到 let,JS 用了整整18年!

在塊中重複宣告:

從var 到 let,JS 用了整整18年!

在兩個塊中分別宣告:

從var 到 let,JS 用了整整18年!

重新賦值:

從var 到 let,JS 用了整整18年!

所以,當在同一個作用域內,使用let重複宣告,是會報錯的,但是可以被重新賦值。

4. 不會作為window 的屬性

var 宣告的全域性變數:

從var 到 let,JS 用了整整18年!

let 宣告的全域性變數:

從var 到 let,JS 用了整整18年!

const 宣告一個量

const這也是ES6新增的語法,它是用於宣告一個常量的,這個常量的值不可被修改。

宣告一個常量

從var 到 let,JS 用了整整18年!

使用const 時必須要同時指定這個常量的值,否則會報錯。

從var 到 let,JS 用了整整18年!

const的作用域

從var 到 let,JS 用了整整18年!

const宣告的常量的作用域也是塊級作用域,和let一樣。

const 的值不可被修改

const宣告建立一個值的只讀引用。但這並不意味著它所持有的值是不可變的,只是變數識別符號不能重新分配。

  • 對於簡單資料型別,值就儲存在變數指向的那個記憶體地址。
  • 對於複合型別的資料,變數指向的記憶體地址,時這個地址不可被修改,至於指向的實際的資料,是可以被修改的。

從var 到 let,JS 用了整整18年!

總結

let 總結

  • let宣告的變數存在暫時性死區,建立過程存在提升,初始化過程不會被提升。
  • let宣告的變數具有塊級作用域
  • let宣告的變數不允許重複宣告
  • let宣告的變數不會作為window的屬性

const 總結

  • 宣告時必須要初始化一個值
  • 常量值不可更改
  • 其他和let特性一樣

JS這門語言的發展是順應歷史的發展,只是JS開發者,會感到心累,因為,在舊版本還需要繼續維護,不能夠果斷放棄,我想說,前人栽樹,後人呵護。

相關文章