最近用淘寶的weex作了個項目,最近稍微閒下來了。正好好久沒有接觸RN了,因此趁這個機會系統的學習一下ES6的相關知識。es6
孔子說:沒有對比就沒有傷害。因此咱們要拿ES6和ES5好好對比的學習。這樣才能明白es6是多少的好,積極的擁抱她!weex
1.let函數
用let聲明的變量,只會在let命令所在的代碼塊內有效。學習
let的塊狀做用域spa
咱們來看一個簡單的例子:指針
'use strict'; { let name = 'cloud'; var age = 21; } name;//ReferenceError: name is not defined age;//21
咱們在let聲明變量name的代碼塊以外去訪問這個變量,結果name是沒有定義的。若是咱們但願在能訪問到name應該怎麼作呢?code
'use strict'; { let name = 'cloud'; var age = 21; name;//cloud }
沒錯,咱們在let聲明變量的代碼塊中去訪問name變量。結果也正如咱們指望的那樣,name的值被訪問到了。對於高級oo語言而言,他們都是基於塊狀做用域的。對象
因此說,let讓咱們聲明的變量也擁有了塊狀做用域這樣一個概念,而不單單是函數做用域了。blog
既然有了塊級做用域,那把let用來聲明循環裏的變量是極好的。作用域
'use strict'; //死循環 for(var i = 0; i < 5; i++){ console.log(i); for(var i = 0; i < 3; i++){ console.log(i); } } for(let i = 0; i < 5; i++){ console.log(i); for(let i = 0; i < 3; i++){ console.log(i); } }
若是沒有let的話,上面代碼中的內循環每次都會把var聲明的變量i重置爲0,因此毫無疑問,這是一個死循環。因此咱們必須把內循環中變量i換成變量j,或者其餘的名稱。可是這也會帶來一個反作用,就是循環完成之後的i,被泄露成了全局變量。
'use strict'; for(var i = 0; i < 5; i++){ i;//0,1,2,3,4 } i;//5 for(let i = 0; i < 5; i++){ i;//0,1,2,3,4 } i;//ReferenceError: i is not defined
let聲明的變量不存在變量聲明提高
'use strict'; name; //undefined age; //ReferenceError: age is not defined var name = 'cloud'; let age = 21;
用var聲明的變量name,雖然咱們在name使用後才聲明並給其賦值,可是由於變量聲明提高的緣由,咱們看到name已經聲明瞭,只是其值是undefined而已。可是用let聲明的age變量,卻沒有定義。因此說let是不存在變量聲明提高的。
let的暫時性死區(temporal dead zone,簡稱TDZ)
只要是塊級做用域中存在let命令,它所在的區域就成爲了暫時性死區,使用let命令聲明變量以前,該變量都是不可用的。同時該變量再也不受到外部的影響。
var name = 'new cloud';
{ //TDZ start name = 'cloud'; name;//ReferenceError: name is not defined let name; //TDZ end name;//undefined let name = 'cloud'; name;//cloud }
如上代碼,在let聲明name以前,那麼這個變量都是不可用的。因此這也帶來一個問題,當咱們使用typeof這樣的反射機制來檢測咱們的所需的變量是否按照咱們設想的那樣,typeof再也不是一個堅決不移的忠臣了,它也會報錯了。
{ typeof name;//undefined var name = 'cloud'; typeof name;//ReferenceError: name is not defined let name = 'cloud'; }
let塊狀做用域內聲明的變量,不容許重複聲明。
1.
'use strict'; var name = 'cloud'; var name = 'new cloud'; name;//new cloud
2.
'use strict'; { let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; let name = 'new cloud'; name; //SyntaxError: Identifier 'name' has already been declared }
第二段代碼中的全部聲明方式,都會報錯。name已經被聲明。
'use strict'; function setName(name){ let name = name;//SyntaxError: Identifier 'name' has already been declared { let name = 'new cloud'; console.log(name);//new cloud } console.log(name);//cloud } setName('cloud');
一樣,在函數中從新聲明變量也會報錯的。
2.const
const是一個只讀的常量。一旦聲明,就不可更改。
'use strict'; const PI = 3.14; PI = 3.1415;//TypeError: Assignment to constant variable
若是用const聲明瞭常量,可是並無去初始化它。那麼,也是會報錯的。
'use strict'; const PI;//SyntaxError: Missing initializer in const declaration
一樣,const
的做用域與let
命令相同:只在聲明所在的塊級做用域內有效。const
命令聲明的常量也是不提高,一樣存在暫時性死區,只能在聲明的位置後面使用。const
聲明的常量,也與let
同樣不可重複聲明。
若是咱們用const來聲明一個引用類型的話。const只能保證指針域不變,可是並不能保證數據域是不可變動的。
'use strict'; const employee = {}; employee['name'] = 'cloud'; employee['age'] = 21; employee = {}; //TypeError: "employee " is read-only employee['name'] = 'new cloud'; console.log(employee.name);//new cloud
若是想把一個對象完成的凍結的話,應該是用Object.freeze()方法。
const employee = Object.freeze({}); employee.name= 'cloud';//TypeError: Can't add property prop, object is not extensible