1. 程式人生 > >24-撩課大前端-面試寶典-第二十四篇

24-撩課大前端-面試寶典-第二十四篇

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方法。