ECMAScript 6.0(簡稱 ES6)是 JavaScript 語言的下一代標(biāo)準(zhǔn)贷掖,已經(jīng)在 2015 年 6 月正式發(fā)布。
ES6新增語法:
-
let
-
ES6
新增了let
關(guān)鍵字剂府,與var
類似自脯,用于聲明變量剩檀。
-
用
let
聲明的變量只在它所在的代碼塊內(nèi)有效{ var a = 10; let b = 20; } console.log(a); console.log(b);
for
循環(huán)的計(jì)數(shù)器澄干,就很合適使用let
命令。使用
var
關(guān)鍵字聲明的for
循環(huán)跷跪,在全局范圍內(nèi)都有效每次循環(huán)改變的是i
的值馋嗜,函數(shù)內(nèi)部的i
指向全局的i
,而此時(shí)for
循環(huán)早已結(jié)束吵瞻,則i
輸出的是for
循環(huán)最后一輪的值葛菇。var a = []; for (var i = 0; i < 5; i++) { a[i] = function() { console.log(i); } } a[3]();
使用
let
關(guān)鍵字聲明的for
循環(huán),此時(shí)的i
只在本輪的循環(huán)有效橡羞,每次循環(huán)的i
都是一個(gè)新的變量眯停,JavaScript 引擎內(nèi)部會(huì)記住上一輪循環(huán)的值,初始化本輪的變量i
時(shí)卿泽,就在上一輪循環(huán)的基礎(chǔ)上進(jìn)行計(jì)算佩番。var a = []; for (let i = 0; i < 5; i++) { a[i] = function() { console.log(i); } } a[3]();
另外使用
for
循環(huán)有一個(gè)特別之處墩虹,就是設(shè)置循環(huán)變量的那部分是一個(gè)父作用域包晰,而循環(huán)體內(nèi)部是一個(gè)單獨(dú)的子作用域赴穗。for (let i = 0; i < 3; i++) { let i = 'abc'; console.log(i); }
-
2.
let
不存在變量提升
```javascript
console.log(a);
var a = 1;
console.log(b);
let b = 2;
```
3.暫時(shí)性死區(qū)
只要塊級(jí)作用域內(nèi)存在
let
命令,它所聲明的變量就“綁定”(binding)這個(gè)區(qū)域覆致,不再受外部的影響侄旬。下面代碼中肺蔚,存在全局變量
tmp
煌妈,但是塊級(jí)作用域內(nèi)let
又聲明了一個(gè)局部變量tmp
,導(dǎo)致后者綁定這個(gè)塊級(jí)作用域宣羊,所以在let
聲明變量前璧诵,對(duì)tmp
賦值會(huì)報(bào)錯(cuò)。應(yīng)該就是仇冯,只要在一個(gè)塊級(jí)作用域內(nèi)之宿,存在
let
關(guān)鍵字,那么let
關(guān)鍵字初始化變量之前該變量不可用苛坚,即便全局作用域存在同名變量也不可用比被。凡是在聲明之前就使用這些變量色难,就會(huì)報(bào)錯(cuò)。
-
總之等缀,在代碼塊內(nèi)枷莉,使用
let
命令聲明變量之前,該變量都是不可用的尺迂。這在語法上笤妙,稱為“暫時(shí)性死區(qū)”(temporal dead zone,簡稱 TDZ)噪裕。var tmp = 123; if (true) { //start TDZ tmp = 'abc'; let tmp;//end TDZ }
4.變量不允許重復(fù)定義
let
不允許在相同作用域內(nèi)蹲盘,重復(fù)聲明同一個(gè)變量let
也不能重復(fù)聲明var
聲明過的變量var
也不能重復(fù)聲明let
聲明過的變量-
因此,不能在函數(shù)內(nèi)部重新聲明參數(shù)
let a = 1; let a = 2; //Uncaught SyntaxError: Identifier 'a' has already been declared var a = 1; let a = 2; //Uncaught SyntaxError: Identifier 'a' has already been declared
5.塊級(jí)作用域
ES6 允許塊級(jí)作用域的任意嵌套膳音。
-
內(nèi)層作用域可以定義外層作用域的同名變量召衔。(外部不能使用內(nèi)部定義的變量,但內(nèi)部可以使用外部的變量)
{ let x = 1; { let y = 2; { let z = 3; let x = 'new1'; console.log(x); console.log(y); } } console.log(z); }
-
函數(shù)與塊級(jí)作用域
-
ES5 規(guī)定祭陷,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明薄嫡,不能在塊級(jí)作用域聲明。
if (true) { function a() {} } switch (1) { case 1: function b() {}; break; }
但是颗胡,瀏覽器沒有遵守這個(gè)規(guī)定毫深,為了兼容以前的舊代碼,還是支持在塊級(jí)作用域之中聲明函數(shù)毒姨,因此上面兩種情況實(shí)際都能運(yùn)行哑蔫,不會(huì)報(bào)錯(cuò)。
ES6 引入了塊級(jí)作用域弧呐,明確允許在塊級(jí)作用域之中聲明函數(shù)闸迷。ES6 規(guī)定,塊級(jí)作用域之中俘枫,函數(shù)聲明語句的行為類似于
let
腥沽,在塊級(jí)作用域之外不可引用。-
如果改變了塊級(jí)作用域內(nèi)聲明的函數(shù)的處理規(guī)則鸠蚪,顯然會(huì)對(duì)老代碼產(chǎn)生很大影響今阳。為了減輕因此產(chǎn)生的不兼容問題,ES6 在附錄B里面規(guī)定茅信,瀏覽器的實(shí)現(xiàn)可以不遵守上面的規(guī)定盾舌,有自己的行為方式。
- 允許在塊級(jí)作用域內(nèi)聲明函數(shù)蘸鲸。
- 函數(shù)聲明類似于
var
妖谴,即會(huì)提升到全局作用域或函數(shù)作用域的頭部。 - 同時(shí)酌摇,函數(shù)聲明還會(huì)提升到所在的塊級(jí)作用域的頭部膝舅。
注意嗡载,上面三條規(guī)則只對(duì) ES6 的瀏覽器實(shí)現(xiàn)有效,其他環(huán)境的實(shí)現(xiàn)不用遵守仍稀,還是將塊級(jí)作用域的函數(shù)聲明當(dāng)作
let
處理鼻疮。 所以,根據(jù)這三條規(guī)則琳轿,瀏覽器的 ES6 環(huán)境中判沟,塊級(jí)作用域內(nèi)聲明的函數(shù),行為類似于
var
聲明的變量崭篡。總之挪哄,考慮到環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級(jí)作用域內(nèi)聲明函數(shù)琉闪。如果確實(shí)需要迹炼,也應(yīng)該寫成函數(shù)表達(dá)式,而不是函數(shù)聲明語句颠毙。
-
-
const
-
const
聲明一個(gè)只讀的常量斯入。一旦聲明,常量的值就不能改變蛀蜜;這意味著刻两,const
一旦聲明變量,就必須立即初始化滴某,不能留到以后賦值磅摹。const ABC = 123; ABC = 456;
-
```javascript
const DEF;
//× Uncaught SyntaxError: Missing initializer in const declaration
```
-
const
的作用域與let
命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。{ const ABC = 123; } console.log(ABC);
-
const
命令聲明的常量也是不提升霎奢,同樣存在暫時(shí)性死區(qū)户誓,只能在聲明的位置后面使用。console.log(ABC); const ABC = 123;
-
const
聲明的常量幕侠,也與let
一樣不可重復(fù)聲明帝美。const ABC = 123; const ABC = 456; //Uncaught SyntaxError: Identifier 'ABC' has already been declared
ES6 聲明變量的六種方法
ES5 只有兩種聲明變量的方法:var
命令和function
命令。ES6 除了添加let
和const
命令晤硕,后面章節(jié)還會(huì)提到悼潭,另外兩種聲明變量的方法:import
命令和class
命令。所以窗骑,ES6 一共有 6 種聲明變量的方法女责。