1赋除、es5和es6的區(qū)別,說(shuō)一下你所知道的es6
ECMAScript5戳护,即ES5金抡,是ECMAScript的第五次修訂瀑焦,于2009年完成標(biāo)準(zhǔn)化ECMAScript6,即ES6梗肝,是ECMAScript的第六次修訂榛瓮,于2015年完成,也稱(chēng)ES2015ES6是繼ES5之后的一次改進(jìn)巫击,相對(duì)于ES5更加簡(jiǎn)潔禀晓,提高了開(kāi)發(fā)效率ES6新增的一些特性:
1)let聲明變量和const聲明常量,兩個(gè)都有塊級(jí)作用域ES5中是沒(méi)有塊級(jí)作用域的坝锰,并且var有變量提升粹懒,在let中,使用的變量一定要進(jìn)行聲明
2)箭頭函數(shù)ES6中的函數(shù)定義不再使用關(guān)鍵字function()顷级,而是利用了()=>來(lái)進(jìn)行定義
3)模板字符串模板字符串是增強(qiáng)版的字符串凫乖,用反引號(hào)(`)標(biāo)識(shí),可以當(dāng)作普通字符串使用愕把,也可以用來(lái)定義多行字符串
4)解構(gòu)賦值ES6 允許按照一定模式拣凹,從數(shù)組和對(duì)象中提取值,對(duì)變量進(jìn)行賦值
5)for of循環(huán)for...of循環(huán)可以遍歷數(shù)組恨豁、Set和Map結(jié)構(gòu)嚣镜、某些類(lèi)似數(shù)組的對(duì)象、對(duì)象橘蜜,以及字符串
6)import菊匿、export導(dǎo)入導(dǎo)出ES6標(biāo)準(zhǔn)中,Js原生支持模塊(module)计福。將JS代碼分割成不同功能的小塊進(jìn)行模塊化跌捆,將不同功能的代碼分別寫(xiě)在不同文件中,各模塊只需導(dǎo)出公共接口部分象颖,然后通過(guò)模塊的導(dǎo)入的方式可以在其他地方使用
7)set數(shù)據(jù)結(jié)構(gòu)Set數(shù)據(jù)結(jié)構(gòu)佩厚,類(lèi)似數(shù)組。所有的數(shù)據(jù)都是唯一的说订,沒(méi)有重復(fù)的值抄瓦。它本身是一個(gè)構(gòu)造函數(shù)
8)... 展開(kāi)運(yùn)算符可以將數(shù)組或?qū)ο罄锩娴闹嫡归_(kāi);還可以將多個(gè)值收集為一個(gè)變量
9)修飾器 @decorator是一個(gè)函數(shù)陶冷,用來(lái)修改類(lèi)甚至于是方法的行為钙姊。修飾器本質(zhì)就是編譯時(shí)執(zhí)行的函數(shù)
10)class 類(lèi)的繼承ES6中不再像ES5一樣使用原型鏈實(shí)現(xiàn)繼承,而是引入Class這個(gè)概念11)async埂伦、await使用 async/await, 搭配promise,可以通過(guò)編寫(xiě)形似同步的代碼來(lái)處理異步流程, 提高代碼的簡(jiǎn)潔性和可讀性async 用于申明一個(gè) function 是異步的煞额,而 await 用于等待一個(gè)異步方法執(zhí)行完成
12)promisePromise是異步編程的一種解決方案,比傳統(tǒng)的解決方案(回調(diào)函數(shù)和事件)更合理、強(qiáng)大
13)SymbolSymbol是一種基本類(lèi)型膊毁。Symbol 通過(guò)調(diào)用symbol函數(shù)產(chǎn)生胀莹,它接收一個(gè)可選的名字參數(shù),該函數(shù)返回的symbol是唯一的
14)Proxy代理使用代理(Proxy)監(jiān)聽(tīng)對(duì)象的操作媚媒,然后可以做一些相應(yīng)事情
2嗜逻、var涩僻、let缭召、const之間的區(qū)別
var聲明變量可以重復(fù)聲明,而let不可以重復(fù)聲明
var是不受限于塊級(jí)的逆日,而let是受限于塊級(jí)
var會(huì)與window相映射(會(huì)掛一個(gè)屬性)嵌巷,而let不與window相映射
var可以在聲明的上面訪問(wèn)變量,而let有暫存死區(qū)室抽,在聲明的上面訪問(wèn)變量會(huì)報(bào)錯(cuò)
const聲明之后必須賦值搪哪,否則會(huì)報(bào)錯(cuò)
const定義不可變的量,改變了就會(huì)報(bào)錯(cuò)
const和let一樣不會(huì)與window相映射坪圾、支持塊級(jí)作用域晓折、在聲明的上面訪問(wèn)變量會(huì)報(bào)錯(cuò)
3、使用箭頭函數(shù)應(yīng)注意什么兽泄?
(1)用了箭頭函數(shù)漓概,this就不是指向window,而是父級(jí)(指向是可變的)
(2)不能夠使用arguments對(duì)象
(3)不能用作構(gòu)造函數(shù)病梢,這就是說(shuō)不能夠使用new命令胃珍,否則會(huì)拋出一個(gè)錯(cuò)誤
(4)不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)
4蜓陌、ES6的模板字符串有哪些新特性觅彰?并實(shí)現(xiàn)一個(gè)類(lèi)模板字符串的功能
基本的字符串格式化。
將表達(dá)式嵌入字符串中進(jìn)行拼接钮热。
用${}
來(lái)界定在ES5時(shí)我們通過(guò)反斜杠()來(lái)做多行字符串或者字符串一行行拼接填抬。
ES6反引號(hào)(``)就能解決類(lèi)模板字符串的功能
let name = 'web';
let age = 10;
let str = '你好,${name} 已經(jīng) ${age}歲了'
str = str.replace(/\$\{([^}]*)\}/g,function(){
return eval(arguments[1]);
})
console.log(str);//你好隧期,web 已經(jīng) 10歲了
5飒责、介紹下 Set、Map的區(qū)別厌秒?
應(yīng)用場(chǎng)景Set用于數(shù)據(jù)重組读拆,Map用于數(shù)據(jù)儲(chǔ)存Set:
(1)成員不能重復(fù)
(2)只有鍵值沒(méi)有鍵名,類(lèi)似數(shù)組
(3)可以遍歷鸵闪,方法有add, delete,has
Map:
(1)本質(zhì)上是健值對(duì)的集合檐晕,類(lèi)似集合
(2)可以遍歷,可以跟各種數(shù)據(jù)格式轉(zhuǎn)換
6、ECMAScript 6 怎么寫(xiě) class 辟灰,為何會(huì)出現(xiàn) class个榕?
ES6的class可以看作是一個(gè)語(yǔ)法糖,它的絕大部分功能ES5都可以做到芥喇,新的class寫(xiě)法只是讓對(duì)象原型的寫(xiě)法更加清晰西采、更像面向?qū)ο缶幊痰恼Z(yǔ)法
//定義類(lèi)
class Point {
constructor(x,y) {
//構(gòu)造方法
this.x = x; //this關(guān)鍵字代表實(shí)例對(duì)象
this.y = y;
} toString() {
return '(' + this.x + ',' + this.y + ')';
}
}
7、Promise構(gòu)造函數(shù)是同步執(zhí)行還是異步執(zhí)行继控,那么 then 方法呢械馆?
promise構(gòu)造函數(shù)是同步執(zhí)行的,then方法是異步執(zhí)行的
8武通、setTimeout霹崎、Promise、Async/Await 的區(qū)別
事件循環(huán)中分為宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列
其中setTimeout的回調(diào)函數(shù)放到宏任務(wù)隊(duì)列里冶忱,等到執(zhí)行棧清空以后執(zhí)行promise.then里的回調(diào)函數(shù)會(huì)放到相應(yīng)宏任務(wù)的微任務(wù)隊(duì)列里尾菇,等宏任務(wù)里面的同步代碼執(zhí)行完再執(zhí)行async函數(shù)表示函數(shù)里面可能會(huì)有異步方法,await后面跟一個(gè)表達(dá)式
async方法執(zhí)行時(shí)囚枪,遇到await會(huì)立即執(zhí)行表達(dá)式派诬,然后把表達(dá)式后面的代碼放到微任務(wù)隊(duì)列里,讓出執(zhí)行棧讓同步代碼先執(zhí)行
9链沼、promise有幾種狀態(tài)默赂,什么時(shí)候會(huì)進(jìn)入catch?
三個(gè)狀態(tài):
pending忆植、fulfilled放可、reject
兩個(gè)過(guò)程:
padding -> fulfilled、padding -> rejected當(dāng)pending為rejectd時(shí)朝刊,會(huì)進(jìn)入catch
10耀里、下面的輸出結(jié)果是多少
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve();
console.log(2);
})
promise.then(() => {
console.log(3);
})
console.log(4);
Promise 新建后立即執(zhí)行,所以會(huì)先輸出 1拾氓,2冯挎,而 Promise.then()內(nèi)部的代碼在 當(dāng)次 事件循環(huán)的 結(jié)尾 立刻執(zhí)行 ,所以會(huì)繼續(xù)輸出4咙鞍,最后輸出3
11房官、使用結(jié)構(gòu)賦值,實(shí)現(xiàn)兩個(gè)變量的值的交換
let a = 1;let b = 2;
[a,b] = [b,a];
12续滋、設(shè)計(jì)一個(gè)對(duì)象翰守,鍵名的類(lèi)型至少包含一個(gè)symbol類(lèi)型,并且實(shí)現(xiàn)遍歷所有key
let name = Symbol('name');
let product = {
[name]:"洗衣機(jī)",
"price":799
};
Reflect.ownKeys(product);
13疲酌、下面Set結(jié)構(gòu)蜡峰,打印出的size值是多少
let s = newSet();
s.add([1]);s.add([1]);
console.log(s.size);
答案:2
兩個(gè)數(shù)組[1]并不是同一個(gè)值了袁,它們分別定義的數(shù)組,在內(nèi)存中分別對(duì)應(yīng)著不同的存儲(chǔ)地址湿颅,因此并不是相同的值都能存儲(chǔ)到Set結(jié)構(gòu)中载绿,所以size為2
14、Promise 中reject 和 catch 處理上有什么區(qū)別
reject 是用來(lái)拋出異常油航,catch 是用來(lái)處理異常
reject 是 Promise 的方法崭庸,而 catch 是 Promise 實(shí)例的方法
reject后的東西,一定會(huì)進(jìn)入then中的第二個(gè)回調(diào)谊囚,如果then中沒(méi)有寫(xiě)第二個(gè)回調(diào)怕享,則進(jìn)入catch
網(wǎng)絡(luò)異常(比如斷網(wǎng)),會(huì)直接進(jìn)入catch而不會(huì)進(jìn)入then的第二個(gè)回調(diào)
15秒啦、使用class 手寫(xiě)一個(gè)promise
//創(chuàng)建一個(gè)Promise的類(lèi)
class Promise{
constructor(executer){//構(gòu)造函數(shù)constructor里面是個(gè)執(zhí)行器
this.status = 'pending';//默認(rèn)的狀態(tài) pending
this.value = undefined//成功的值默認(rèn)undefined
this.reason = undefined//失敗的值默認(rèn)undefined
//狀態(tài)只有在pending時(shí)候才能改變
let resolveFn = value =>{
//判斷只有等待時(shí)才能resolve成功
if(this.status == pending){
this.status = 'resolve';
this.value = value;
}
}
//判斷只有等待時(shí)才能reject失敗
let rejectFn = reason =>{
if(this.status == pending){
this.status = 'reject';
this.reason = reason;
}
}
try{
//把resolve和reject兩個(gè)函數(shù)傳給執(zhí)行器executer
executer(resolve,reject);
}catch(e){
reject(e);//失敗的話(huà)進(jìn)catch
}
}
then(onFufilled,onReject){
//如果狀態(tài)成功調(diào)用onFufilled
if(this.status = 'resolve'){
onFufilled(this.value);
}
//如果狀態(tài)失敗調(diào)用onReject
if(this.status = 'reject'){
onReject(this.reason);
}
}
}
16熬粗、如何使用Set去重
let arr = [12,43,23,43,68,12];
let item = [...new Set(arr)];
console.log(item);//[12, 43, 23, 68]
17、將下面for循環(huán)改成for of形式
let arr = [11,22,33,44,55];
let sum = 0;
for(let i=0;i<arr.length;i++){
sum += arr[i];
}
答案:
let arr = [11,22,33,44,55];
let sum = 0;
for(value of arr){
sum += value;
}
18余境、理解 async/await以及對(duì)Generator的優(yōu)勢(shì)
async await 是用來(lái)解決異步的,async函數(shù)是Generator函數(shù)的語(yǔ)法糖
使用關(guān)鍵字async來(lái)表示灌诅,在函數(shù)內(nèi)部使用 await 來(lái)表示異步
async函數(shù)返回一個(gè) Promise 對(duì)象芳来,可以使用then方法添加回調(diào)函數(shù)
當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到await就會(huì)先返回猜拾,等到異步操作完成即舌,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句
async較Generator的優(yōu)勢(shì):
(1)內(nèi)置執(zhí)行器。Generator 函數(shù)的執(zhí)行必須依靠執(zhí)行器挎袜,而 Aysnc 函數(shù)自帶執(zhí)行器顽聂,調(diào)用方式跟普通函數(shù)的調(diào)用一樣
(2)更好的語(yǔ)義。async 和 await 相較于 * 和 yield 更加語(yǔ)義化
(3)更廣的適用性盯仪。yield命令后面只能是 Thunk 函數(shù)或 Promise對(duì)象紊搪,async函數(shù)的await后面可以是Promise也可以是原始類(lèi)型的值
(4)返回值是 Promise。async 函數(shù)返回的是 Promise 對(duì)象全景,比Generator函數(shù)返回的Iterator對(duì)象方便耀石,可以直接使用 then() 方法進(jìn)行調(diào)用
19、forEach爸黄、for in滞伟、for of三者區(qū)別
forEach更多的用來(lái)遍歷數(shù)組
for in 一般常用來(lái)遍歷對(duì)象或json
for of數(shù)組對(duì)象都可以遍歷,遍歷對(duì)象需要通過(guò)和Object.keys()
for in循環(huán)出的是key炕贵,for of循環(huán)出的是value
20梆奈、說(shuō)一下es6的導(dǎo)入導(dǎo)出模塊
導(dǎo)入通過(guò)import關(guān)鍵字
// 只導(dǎo)入一個(gè)
import {sum} from "./example.js"
// 導(dǎo)入多個(gè)
import {sum,multiply,time} from "./exportExample.js"
// 導(dǎo)入一整個(gè)模塊
import * as example from "./exportExample.js"
導(dǎo)出通過(guò)export關(guān)鍵字
//可以將export放在任何`變量,函數(shù)或類(lèi)聲明的前面
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
//也可以使用大括號(hào)指定所要輸出的一組變量
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
//使用export default時(shí),對(duì)應(yīng)的import語(yǔ)句不需要使用大括號(hào)
let bosh = function crs(){}
export default bosh;
import crc from 'crc';
//不使用export default時(shí)称开,對(duì)應(yīng)的import語(yǔ)句需要使用大括號(hào)
let bosh = function crs(){}
export bosh;
import {crc} from 'crc';