衆所周知,JavaScript做爲弱類型語言,一直是精華與糟粕共存,許多「詭異」的地方咱們不得不接受並使用。其實ES6(又稱ECMAScript 2015)在2015年6月就已經正式發佈了,其中提出的不少新的特性讓JavaScript更加完善和豐富,對於前端開發者可謂一大福音。html
目前各大瀏覽器的最新版本對ES6的支持度也愈來愈高,大部分的特性都實現了( ES6 支持 )。另外如今也有不少的轉換器(如Babel
),將ES6和ES7的代碼轉換爲ES5的代碼,這就意味着咱們如今就可使用這些新特性應用到咱們的項目中去。前端
本篇對ES6中的關於變量部分的新特性進行介紹,本系列傳送門:git
以往JavaScript是不具備塊級做用域的,一個函數才能構成一個做用域,局部變量在整個函數內都是有定義的,舉個栗子es6
for(var i = 0;i < 10;i++){ } console.log(i); //輸出10
最後在for循環以後,i變量僅用於for循環,但在卻被泄露成全局變量造成變量污染,這就是不合理的地方,經過ES6中定義的let
關鍵字能夠造成僅做用於該塊做用域的局部變量,github
//ES6環境下 for(let i = 0;i < 10;i++){ } console.log(i); //輸出ReferenceError(未定義)
利用Babel將這段ES6代碼轉換爲ES5代碼後,其實是對ES5的代碼對其原理進行模擬達到一致的效果,所以能夠幫助咱們的理解:編程
//Babel轉換後 for (var _i = 0; _i < 10; _i++) { } console.log(i); //輸出ReferenceError(未定義)
能夠看到,對於let聲明的局部變量,若是外部有相同定義,會經過添加下劃線將其轉換爲另外的變量,表達意思就是let將該變量僅在該塊做用域內可用。數組
再舉個栗子:瀏覽器
var a = []; for (var i = 0; i < 3; i++) { a[i] = function () { console.log(i); }; } a[1](); //輸出3 a[2](); //輸出3
上面的代碼的三次循環中i始終爲同一個變量,值最後爲3。a數組中的函數讀到的i也是這個值,所以都是輸出3,這跟咱們想要的結果並不一致。而利用let這個新特性能夠很好的解決這個問題:babel
//ES6環境 var a = []; for (let i = 0; i < 3; i++) { a[i] = function () { console.log(i); }; } a[1](); //輸出1 a[2](); //輸出2
//Babel轉換後 var a = []; var _loop = function _loop(i) { a[i] = function () { console.log(i); }; }; for (var i = 0; i < 3; i++) { _loop(i); } a[1](); //輸出1 a[2](); //輸出2
此次轉換後稍微變得複雜了一些,其實是新定義一個函數,將循環變量i做爲參數傳進去,能夠這樣理解ES6中代碼經過let將三次循環中的i固定於各自的塊做用域中,互不干擾。數據結構
另外關於let要注意的幾點:
console.log(a); //輸出ReferenceError(未定義),let聲明的變量不會變量提高,這也是規範咱們的代碼先聲明後使用。 let a = 3; let a = 4; //錯誤,let聲明的變量不能重複定義
總之,用let讓咱們的代碼更加規範避免了不少問題,所以儘量使用let代替var.
let
相似const
也能造成塊做用域,不一樣點在於const聲明的變量爲常量,不可改變舉個栗子:
if(true){ const MAX = 999; MAX = 3; //報錯:"MAX" is read-only } console.log(MAX);//輸出ReferenceError(未定義)
能夠看出const也造成塊級做用域,並且值不可改變,有一點要注意的是不能改變的是const類型變量存儲的東西,舉個栗子更好理解:
const person = {}; person.name = 'vicfeel'; //正確,person存儲的是指向該對象的地址,對象內容能夠改變 person = {}; //報錯:"person" is read-only,該地址不能改變
以往多個變量的賦值咱們使用以下的方式:
var a = 1; var b = 2; var c = 3; var d = 4,e = 5,f = 5;
ES6中增長一種更便捷的多變量賦值方法:
var [a,b,c] = [1,2,3];
系統會自動對數組內元素進行對應賦值,也就是說咱們也能夠用這種方式來進行變量的聲明:
//ES6環境下 var arr = [1,2,3]; var [a,b,c] = arr;
咱們用Babel看一下是如何模擬的:
//Babel轉換後 var _ref = [1, 2,3]; var a = _ref[0]; var b = _ref[1]; var c = _ref[2];
能夠看到是經過數組下標依次向後賦值,下面我對多種狀況進行了賦值測試:
{ //數量不對應 let [a,b,c] = [1,2]; console.log(a); //1 console.log(b); //2 console.log(c); //undefined //按照上面babel轉換的理解,c = _ref[2]不存在該要素所以c爲undefined } { //多層數組 let [a,[b,c],d] = [1,[2,3],4]; console.log(a); //1 console.log(b); //2 console.log(c); //3 console.log(d); //4 } { //多層不對應 let [a,[b,c],d] = [1,[2],3]; console.log(a); //1 console.log(b); //2 console.log(c); //undefined console.log(d); //3 } { //對應值非數組 let [a,b,c] = 1; //報錯 let [a,b,c] = false; //報錯,等號右邊必須爲可遍歷對象 }
瞭解映射的原理以後,一個很好的應用場景就是交換數值,如今能夠這樣簡單的實現:
//ES6環境下 let [x,y] = [0,1]; [x,y] = [y,x];
//ES6環境下 let [a, b = 2,c] = [1]; //y無對應值時,默認值則爲2 console.log(a); //1 console.log(b); //2 console.log(c); //undefined
看一下ES5的模擬
//Babel轉換後 var _ref = [1]; var a = _ref[0]; var _ref$ = _ref[1]; var b = _ref$ === undefined ? 2 : _ref$; //經過‘===’嚴格等於判斷是否爲undefined,是的話採用默認值 var c = _ref[2]; //因此是undefined
直接看栗子:
//ES6環境下 var { oA, oB } = { oA: "a", oB: "b" }; console.log(oA); //"a" console.log(oB); //"b"
看一下ES5的模擬
//Babel轉換後 var _oA$oB = { oA: "aaa", oB: "bbb" }; var oA = _oA$oB.oA; //原來是經過同名屬性進行對應 var oB = _oA$oB.oB; console.log(oA); console.log(oB);
瞭解了對應的原理以後,咱們再作一下其它狀況的測試:
{ //順序改變 var { oA, oB } = { oB: "a", oA: "b" }; console.log(oA); //"b" console.log(oB); //"a" } { //數量不對應 var { oA, oB } = { oA: "a"}; console.log(oA); //"a" console.log(oB); //undefined,等號右邊對象找不到oB屬性 }
掌握這種方法,能夠簡化不少以前操做,如獲取一個對象的某些屬性,能夠經過如下方式:
//ES6環境下 var person = { name:'Vicfeel', age:'23', sex:'Male' } let {name,age,sex} = person; console.log(name);//Vicfeel console.log(age); //23 console.log(sex); //Male
參考Reference
http://www.ecma-international.org/ecma-262/6.0/index.html
http://es6.ruanyifeng.com/
http://www.cnblogs.com/Wayou/p/es6_new_features.html
http://www.cnblogs.com/snandy/archive/2015/05/10/4485832.html
博文做者:vicfeel
博文出處:http://www.cnblogs.com/vicfeel 本文版權歸做者和博客園共有,歡迎轉載,但須保留此段聲明,並給出原文連接,謝謝合做! 若是閱讀了本文章,以爲有幫助,您能夠爲個人博文點擊「推薦一下」!