for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, i * 1000 ); } 閉包在這裏能起什麼做用? 上面的代碼不會按預期顯示值0,1,2,3,和4, 而是會顯示5,5,5,5,和5。 緣由是,在循環中執行的每一個函數將整個循環完成以後被執行, 所以,將會引用存儲在 i中的最後一個值,那就是5。 閉包能夠經過爲每次迭代建立一個惟一的範圍, 存儲範圍內變量的每一個惟一的值, 來防止這個問題, 以下: for (var i = 0; i < 5; i++) { (function(x) { setTimeout(function() { console.log(x); }, x * 1000 ); })(i); } 這就會按預期輸出0,1,2,3,和4到控制檯。
ES2015特指在2015年發佈的新一代JS語言標準,
ES6泛指下一代JS語言標準,
包含ES201五、ES201六、ES201七、ES2018等。
現階段在絕大部分場景下,
ES2015默認等同ES6。
ES5泛指上一代語言標準。
ES2015能夠理解爲ES5和ES6的時間分界線。
Iterator是ES6中一個很重要概念, 它並非對象, 也不是任何一種數據類型。 由於ES6新增了Set、Map類型, 他們和Array、Object類型很像,Array、Object都是能夠遍歷的, 可是Set、Map都不能用for循環遍歷, 解決這個問題有兩種方案, 一種是爲Set、Map單獨新增一個用來遍歷的API, 另外一種是爲Set、Map、Array、Object新增一個統一的遍歷API, 顯然, 第二種更好, ES6也就順其天然的須要一種設計標準, 來統一全部可遍歷類型的遍歷方式。 Iterator正是這樣一種標準。或者說是一種規範理念。 就好像JavaScript是ECMAScript標準的一種具體實現同樣, Iterator標準的具體實現是Iterator遍歷器。 Iterator標準規定,全部部署了key值爲[Symbol.iterator], 且[Symbol.iterator]的value是標準的Iterator接口函數(標準的Iterator接口函數: 該函數必須返回一個對象, 且對象中包含next方法, 且執行next()能返回包含value/done屬性的Iterator對象)的對象, 都稱之爲可遍歷對象, next()後返回的Iterator對象也就是Iterator遍歷器。 obj就是可遍歷的, 由於它遵循了Iterator標準, 且包含[Symbol.iterator]方法, 方法函數也符合標準的Iterator接口規範。 //obj.[Symbol.iterator]() 就是Iterator遍歷器 let obj = { data: [ 'hello', 'world' ], [Symbol.iterator]() { const self = this; let index = 0; return { next() { if (index < self.data.length) { return { value: self.data[index++], done: false }; } else { return { value: undefined, done: true }; } } }; } }; ES6給Set、Map、Array、String都加上了[Symbol.iterator]方法, 且[Symbol.iterator]方法函數也符合標準的Iterator接口規範, 因此Set、Map、Array、String默認都是能夠遍歷的。 //Array let array = ['red', 'green', 'blue']; array[Symbol.iterator]() //Iterator遍歷器 array[Symbol.iterator]().next() //{value: "red", done: false} //String let string = '1122334455'; string[Symbol.iterator]() //Iterator遍歷器 string[Symbol.iterator]().next() //{value: "1", done: false} //set let set = new Set(['red', 'green', 'blue']); set[Symbol.iterator]() //Iterator遍歷器 set[Symbol.iterator]().next() {value: "red", done: false} Map let map = new Map(); let obj= {map: 'map'}; map.set(obj, 'mapValue'); map[Symbol.iterator]().next() {value: Array(2), done: false}
module、export、import 是ES6用來統一前端模塊化方案的設計思路和實現方案。 export、import的出現統一了前端模塊化的實現方案, 整合規範了瀏覽器/服務端的模塊化方法, 用來取代傳統的AMD/CMD、requireJS、seaJS、commondJS等等一系列前端模塊不一樣的實現方案, 使前端模塊化更加統一規範, JS也能更加能實現大型的應用程序開發。 import引入的模塊是靜態加載(編譯階段加載) 而不是動態加載(運行時加載)。 import引入export導出的接口值是動態綁定關係, 即經過該接口,能夠取到模塊內部實時的值。
1、經常使用箭頭函數來取代var self = this;的作法。 2、經常使用let取代var命令。 3、經常使用數組/對象的結構賦值來命名變量,結構更清晰,語義更明確,可讀性更好。 4、在長字符串多變量組合場合,用模板字符串來取代字符串累加,能取得更好地效果和閱讀體驗。 5、用Class類取代傳統的構造函數,來生成實例化對象。 6、在大型應用開發中,要保持module模塊化開發思惟,分清模塊之間的關係,經常使用import、export方法。