與var不一樣,新的變量聲明方式帶來了一些不同的特性,其中最重要的兩個特性就是提供了塊級做用域與再也不具有變量提高:html
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代碼在代碼塊之中,分別用let
和var
聲明瞭兩個變量。而後在代碼塊以外調用這兩個變量,結果let
聲明的變量報錯,var
聲明的變量返回了正確的值。這代表,let
聲明的變量只在它所在的代碼塊有效。json
var
命令會發生「變量提高」現象,即變量能夠在聲明以前使用,值爲undefined
。這種現象多多少少是有些奇怪的,按照通常的邏輯,變量應該在聲明語句以後纔可使用。數組
爲了糾正這種現象,let
命令改變了語法行爲,它所聲明的變量必定要在聲明後使用,不然報錯。函數
// var 的狀況 console.log(foo); // 輸出undefined var foo = 2; // let 的狀況 console.log(bar); // 報錯ReferenceError let bar = 2;
上面代碼中,變量foo
用var
命令聲明,會發生變量提高,即腳本開始運行時,變量foo
已經存在了,可是沒有值,因此會輸出undefined
。變量bar
用let
命令聲明,不會發生變量提高。this
這表示在聲明它以前,變量bar
是不存在的,這時若是用到它,就會拋出一個錯誤。spa
let
不容許在相同做用域內,重複聲明同一個變量。指針
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 function func() { let a = 10; let a = 1; }
所以,不能在函數內部從新聲明參數。code
function func(arg) { let arg; } func() // 報錯 function func(arg) { { let arg; } } func() // 不報錯
一樣在塊級做用域有效的另外一個變量聲明方式是 const
,const
聲明一個只讀的常量。一旦聲明,常量的值就不能改變。htm
ES6 中,const
聲明的常量相似於指針,它指向某個引用,也就是說這個「常量」並不是一成不變的,如:對象
{ const ARR = [5,6]; ARR.push(7); console.log(ARR); // [5,6,7] ARR = 10; // TypeError }
有幾個點須要注意:
let
關鍵詞聲明的變量不具有變量提高(hoisting)特性let
和 const
聲明只在最靠近的一個塊中(花括號內)有效const
聲明時,請使用大寫變量,如:CAPITAL_CASINGconst
在聲明時必須被賦值ES6 中,箭頭函數就是函數的一種簡寫形式,使用括號包裹參數,跟隨一個 =>
,緊接着是函數體:
原
var fun = function(){ console.log('hello') } fun();
簡
var fun = () => { console.log('hello') } fun()
注意的地方
1.不能用this,箭頭函數中的this指向window
2.不能使用arguments
例子(this):html內容
<style> #box{ width: 100px; height: 100px; border: 1px solid #000; } </style> </head> <body> <div id="box"></div>
JS內容
原:
var box = document.getElementById("box"); box.onclick = function fun(){ this.style.background = '#f00'; }
效果點擊boxDIV後會變紅色
箭頭:
var box = document.getElementById("box"); box.onclick = () => { this.style.background = '#f00'; }
例子(arguments)
原
function fun(){ console.log(arguments); } fun(1,2,3,4)
效果:
箭頭:
var fun = () => { console.log(arguments); } fun(1,2,3,4)
ES6 容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構
之前,爲變量賦值,只能直接指定值。
let a = 1; let b = 2; let c = 3;
ES6 容許寫成下面這樣。
let [a, b, c] = [1, 2, 3];
(1)本質上,這種寫法屬於「模式匹配」,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。下面是一些使用嵌套數組進行解構的例子。
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3 let [ , , third] = ["foo", "bar", "baz"]; third // "baz" let [x, , y] = [1, 2, 3]; x // 1 y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ['a']; x // "a" y // undefined z // []
(2)若是解構不成功,變量的值就等於undefined
。
let [foo] = []; let [bar, foo] = [1];
以上兩種狀況都屬於解構不成功,foo
的值都會等於undefined
。
(3)另外一種狀況是不徹底解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。這種狀況下,解構依然能夠成功。
let [x, y] = [1, 2, 3]; x // 1 y // 2 let [a, [b], d] = [1, [2, 3], 4]; a // 1 b // 2 d // 4
上面兩個例子,都屬於不徹底解構,可是能夠成功。
(4)json格式
對象的解構賦值
var {a,b,c} = {a:10,c:30,b:20}; //能夠調換順序 console.log(a,b,c); var [a,[b,c],d] = [5,[10,20],30]; //格式對應便可 console.log(a,b,c,d)
與數組同樣,解構也能夠用於嵌套結構的對象。
let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p: [x, { y }] } = obj; x // "Hello" y // "World"
解構賦值容許指定默認值
let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 內部使用嚴格相等運算符(===
),判斷一個位置是否有值。因此,只有當一個數組成員嚴格等於undefined
,默認值纔會生效。
for...of
VS for...in
) for...of
用於遍歷一個迭代器,如數組:
var arr = ["red","green","blue","yellow","black"]; for(var i of arr){ console.log(i); //輸出的直接是值 }
for...in
用來遍歷對象中的屬性:
var arr = ["red","green","blue","yellow","black"]; for(var i in arr){ console.log(i); //輸出的是索引 console.log(arr[i]); }