ES6 慢慢學~
ES5 只有兩種聲明變量的方法:var
命令和function
命令。javascript
ES6 除了添加let
命令和const
命令,另外兩種聲明變量的方法:import
命令和class
命令。java
因此,ES6一共有6 種聲明變量的方法。es6
var
命令能夠聲明變量function
命令聲明函數,後跟一組參數及函數體let
命令用於聲明變量const
命令聲明一個只讀的常量export
命令顯式指定輸出的代碼,再經過import
命令輸入class
關鍵字能夠定義類let
命令和const
命令所聲明的變量or常量只在它所在的代碼塊有效。數組
const
實際上保證的,並非變量的值不得改動,而是變量指向的按個內存地址所保存的數據不得改動。數據結構
- 對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,所以等同於常量。
- 對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針。
const
只能保證這個指針是固定的(即老是指向另外一個固定的地址),至於它指向的數據結構是否是可變的,就徹底不能控制了。const
只聲明不賦值,就會報錯。
for (let i = 0; i < 4; i++) { // ... } console.log(i); // ReferenceError: i is not defined
const student = {}; // 能夠添加一個屬性 student.name = '朝霞的世界'; // 將 student 指向另外一個對象,就會報錯 student = {}; // TypeError: "student" is read-only
ES5 只有全局做用域和函數做用域,沒有塊級做用域,這樣會有一些不合理的場景。函數
- 內層變量可能會覆蓋外層變量
- 用來計數的循環變量泄露爲全局變量
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'zhaoxiajingjing'; } } f(); // undefined
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
ES6 新增了塊級做用域,容許任意嵌套。使得自執行匿名函數表達式就再也不必要了。spa
{{{{ {let insane = 'zhaoxiajingjing'} console.log(insane); // 報錯 }}}};
// 自執行匿名函數 (function () { var tmp = ...; }()); // 塊級做用域寫法 { let tmp = ...; }
只要塊級做用域內存在let
命令或const
命令,它所聲明的變量或常量就「綁定」(binding)這個區域,再也不受外部影響。3d
在代碼塊內,使用let
命令聲明變量以前,該變量都是不可用的。這在語法上,稱爲:暫時性死區(temporal dead zone,簡稱TDZ)指針
if (true) { // TDZ開始 tmp = 'zhaoxiajingjing'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ結束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
let
和const
PK var
- 有效範圍:
var
聲明的變量,會聲明到全局,污染全局變量- 變量提高:
var
聲明的變量,能夠在聲明以前調用- 做用域:使用
var
的做用域有全局做用域、函數做用域- 重複聲明:
var
能重複聲明
let
和const
只在聲明所在的塊級做用域內有效var
聲明的變量,會聲明到全局,污染全局變量
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 window.a[4](); // 10 window.i; // 10
上面代碼中,變量 i
是var
命令聲明的,在全局範圍內有效,因此全局只有一個變量i
。能夠在window
上訪問並獲取到值。code
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6 window.a[4](); // 4 window.i; // undefined
上面代碼中,變量i
是let
聲明的,當前的i
只在本輪循環有效,因此每一次循環的i
都是一個新的變量,因此每次輸出的值不同。
let
聲明的變量僅在塊級做用域內有效,因此在window
上i
的值是undefined
。
for
循環還有一個特別之處,就是設置循環變量的那部分是一個父做用域,而循環體內部是一個單獨的子做用域。
for (let i = 0; i < 3; i++) { let i = 'zhaoxiajingjing'; console.log(i); } // zhaoxiajingjing // zhaoxiajingjing // zhaoxiajingjing
let
和const
聲明的變量or常量不會提高,必定要在聲明後使用,不然報錯var
聲明的變量,能夠在聲明以前調用,值爲undefined
// var 的狀況 console.log(a); // 輸出undefined var a = 2; // let 的狀況 console.log(b); // 報錯ReferenceError let b = 2;
let
和const
能夠在塊級做用域中使用- 使用
var
的做用域有全局做用域、函數做用域
{ var a = 'hello'; let gzh = 'zhaoxiajingjing'; } console.log(a); // hello console.log(gzh); // ReferenceError: gzh is not defined
let
和const
不容許在相同做用域內,重複聲明同一個變量var
能重複聲明
// 報錯 function f(){ let gongzhonghao = 'zhaoxiajingjing'; var gongzhonghao = 'zhaoxiajingjing'; } f();
// 不報錯 function f(){ var gongzhonghao = 'zhaoxiajingjing'; var gongzhonghao = 'zhaoxiajingjing'; } f();
// 報錯 function f(args){ let args = 'zhaoxiajingjing'; } f();
// 不報錯 function f(args){ { let args = 'zhaoxiajingjing'; } } f();
typeof
有什麼影響?參考:ECMAScript 6 入門
http://es6.ruanyifeng.com/#do...