一個人的成功啊,不僅要靠個人的努力,還要考慮到歷史的程式。
18年?
看第一版的ECMA:1997年

看看支援let的版本:2015年

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

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

作用域
在ES6之前,你要知道,只有全域性作用域和函式作用域。
在函式裡面宣告一個變數,在函式外部訪問會報錯:

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

小結:var
存在缺陷,宣告前置,作用域的問題,不像一個程式語言該有的變數宣告。
let的魔法
1. 暫時性死區
先使用,後定義會報錯,不會再像var
那樣隨意:

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

let
宣告的變數必須先宣告並初始化成功後才能被引用,否則,這個變數就不能被引用,進入了暫存死區,就跟死了一樣。
2. 塊級作用域

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

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

在塊中重複宣告:

在兩個塊中分別宣告:

重新賦值:

所以,當在同一個作用域內,使用let
重複宣告,是會報錯的,但是可以被重新賦值。
4. 不會作為window 的屬性
var
宣告的全域性變數:

let
宣告的全域性變數:

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

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

const的作用域

const
宣告的常量的作用域也是塊級作用域,和let
一樣。
const 的值不可被修改
const
宣告建立一個值的只讀引用。但這並不意味著它所持有的值是不可變的,只是變數識別符號不能重新分配。
- 對於簡單資料型別,值就儲存在變數指向的那個記憶體地址。
- 對於複合型別的資料,變數指向的記憶體地址,時這個地址不可被修改,至於指向的實際的資料,是可以被修改的。

總結
let 總結
let
宣告的變數存在暫時性死區,建立過程存在提升,初始化過程不會被提升。let
宣告的變數具有塊級作用域let
宣告的變數不允許重複宣告let
宣告的變數不會作為window
的屬性
const 總結
- 宣告時必須要初始化一個值
- 常量值不可更改
- 其他和
let
特性一樣
JS這門語言的發展是順應歷史的發展,只是JS開發者,會感到心累,因為,在舊版本還需要繼續維護,不能夠果斷放棄,我想說,前人栽樹,後人呵護。