24-撩課大前端-面試寶典-第二十四篇
阿新 • • 發佈:2018-12-28
1.下面的程式碼將輸出什麼?
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到控制檯。
2.ES5、ES6和ES2015有什麼區別?
ES2015特指在2015年釋出的新一代JS語言標準,
ES6泛指下一代JS語言標準,
包含ES2015、ES2016、ES2017、ES2018等。
現階段在絕大部分場景下,
ES2015預設等同ES6。
ES5泛指上一代語言標準。
ES2015可以理解為ES5和ES6的時間分界線。
3.Iterator是什麼,有什麼作用?
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}
4.module、export、import是什麼,有什麼作用?
module、export、import 是ES6用來統一前端模組化方案的設計思路和實現方案。 export、import的出現統一了前端模組化的實現方案, 整合規範了瀏覽器/服務端的模組化方法, 用來取代傳統的AMD/CMD、requireJS、seaJS、commondJS等等一系列前端模組不同的實現方案, 使前端模組化更加統一規範, JS也能更加能實現大型的應用程式開發。 import引入的模組是靜態載入(編譯階段載入) 而不是動態載入(執行時載入)。 import引入export匯出的介面值是動態繫結關係, 即通過該介面,可以取到模組內部實時的值。
5.日常前端程式碼開發中,有哪些值得用ES6去改進的程式設計優化或者規範?
1、常用箭頭函式來取代var self = this;的做法。
2、常用let取代var命令。
3、常用陣列/物件的結構賦值來命名變數,結構更清晰,語義更明確,可讀性更好。
4、在長字串多變數組合場合,用模板字串來取代字串累加,能取得更好地效果和閱讀體驗。
5、用Class類取代傳統的建構函式,來生成例項化物件。
6、在大型應用開發中,要保持module模組化開發思維,分清模組之間的關係,常用import、export方法。