一、塊級做用域數組
ES5只有全局做用域和函數做用域,沒有塊級做用域,所以會出現下面這樣的問題:app
for(var i = 0; i < 10; i ++){ } console.log(i);
代碼塊內聲明的變量,代碼塊外同樣能夠訪問。這種狀況不少時候是不合理的。函數
var arr = []; for(var i = 0; i < 10; i ++){ arr[i] = function () { console.log(i); } } arr[3](); // 10
進行 10
次循環,第一次全局聲明變量 i
,以後每次更新 i
的值,數組 arr
保存着 10
個函數,每一個函數等到運行時訪問全局變量 i
,固然每次調用函數都是輸出 10
。這個問題下面的介紹就能解決。spa
二、基本使用code
ES6新增了 let
命令,和 var
同樣,也是用來聲明變量的。但它所聲明的變量,只在代碼塊內有效。對象
for(let i = 0; i < 10; i ++){ } console.log(i); // error
if(true){ let a = 10; } console.log(a); // error
三、不存在變量提高作用域
ES5中使用 var
是會發生變量提高的:io
console.log(i); var i = 0; // undefined // 等同於 var i; console.log(i); i = 0;
ES6中使用 let
不會:console
console.log(i); // error let i = 10;
四、暫時性死區function
代碼塊內的變量不管是ES5仍是ES6均可以往上查找值的:
var a = 10; if(true){ console.log(a); // 10 } let a = 10; if(true){ console.log(a); // 10 }
可是隻要塊級做用域內使用了 let
命令,它所聲明的變量,就綁定了這個區域,再也不受外部的影響,下面這種狀況會報錯:
let a = 10; if(true){ console.log(a); // error let a; }
由於let
命令沒有變量提高,因此你在變量聲明以前使用該變量就是不行,無論你代碼塊外部作了什麼操做,因此若是你決定使用ES6語法規則,仍是老老實實先定義後使用吧。
五、不容許在同一個做用域內重複聲明變量
ES5中重複聲明變量是沒有問題的:
var a = 10; var a = 20; console.log(a); // 20
ES6很較真,你敢這樣作,我就敢報錯:
let a = 10; let a = 20; // error
別忘了,ES6是有塊級做用域的,因此下面這樣仍是徹底能夠的:
let a = 10; if(true){ let a = 20; console.log(a); } console.log(a); // 20 // 10
如今解決上面那個問題,就很簡單了:
let arr = []; for(let i = 0; i < 10; i ++){ arr[i] = () => { console.log(i); } } arr[3](); // 3
一、基本使用
ES6中聲明一個只讀的常量是用 const
,它與 let
大部分都相同:
但有倆點不一樣。
一、一旦聲明,就要初始化(按照規定,常量最好使用大寫):
const A; // error
因此仍是聲明就當即賦值吧:
const A = 10;
二、第二點不一樣就是,不可後面更改它的值:
const A = 10; A = 20; // error
注意:
因爲在 js
中,一個變量保存着一個複合類型(Array
、Object
、Function
)的數據,僅僅保存的是該數據的地址,因此只要地址不換,就不會報錯:
const MYARRAY = ['apple', 'banana']; MYARRAY.push('orange'); console.log(MYARRAY); // [ "apple", "banana", "orange" ] const MYOBJECT = { username: 'tom' }; MYOBJECT.age = 24; console.log(MYOBJECT); // { username: "tom", age: 24 }
只有把地址都換了,才報錯:
const MYOBJECT = { username: 'tom' }; MYOBJECT = { // error username: 'tom', age: 24 };
上面代碼實際上是爲常量 MYOBJECT
從新賦值了一個對象。