必考:ES 6 語法知道哪些,分別怎么用?
舉例法
let :語句聲明一個塊級作用域的本地變量
const:常量是塊級作用域,很像使用let語句定義的變量。常量的值不能通過重新賦值來改
變,并且不能重新聲明。
箭頭函數 Promise
import :導入由另一個模塊導出的綁定
export :從模塊中導出函數、對象或原始值
默認參數:function multiply(a, b = 1) { return a * b; }
展開操作符:function sum(x, y, z) { return x + y + z;} const numbers = [1, 2, 3]; console.log(sum(...numbers));
-
必考 Promise、Promise.all、Promise.race 分別怎么用?
-
背代碼 Promise 用法
function fn(){ return new Promise((resolve, reject)=>{ 成功時調用 resolve(數據) 失敗時調用 reject(錯誤) }) } fn().then(success, fail).then(success2, fail2)
-
背代碼 Promise.all 用法
Promise.all([promise1, promise2]).then(success1, fail1)
promise1和promise2都成功才會調用success1
-
背代碼 Promise.race 用法
Promise.race([promise1, promise2]).then(success1, fail1)
promise1和promise2只要有一個成功就會調用success1
-
-
必考:手寫函數防抖和函數節流
-
背代碼
// 節流(一段時間執行一次之后,就不執行第二次) function throttle(fn, delay){ let canUse = true return function(){ if(canUse){ fn.apply(this, arguments) canUse = false setTimeout(()=>canUse = true, delay) } } } const throttled = throttle(()=>console.log('hi')) throttled() throttled()
注意,有些地方認為節流函數不是立刻執行的,而是在冷卻時間末尾執行的(相當于施法有吟唱時間),那樣說也是對的。
-
背代碼
// 防抖(一段時間會等,然后帶著一起做了) function debounce(fn, delay){ let timerId = null return function(){ const context = this if(timerId){window.clearTimeout(timerId)} timerId = setTimeout(()=>{ fn.apply(context, arguments) timerId = null },delay) } } const debounced = debounce(()=>console.log('hi')) debounced() debounced()
-
-
必考:手寫AJAX
-
背代碼,完整版
var request = new XMLHttpRequest() request.open('GET', '/a/b/c?name=ff', true); request.onreadystatechange = function () { if(request.readyState === 4 && request.status === 200) { console.log(request.responseText); }}; request.send();
-
背代碼,簡化版
var request = new XMLHttpRequest() request.open('GET', '/a/b/c?name=ff', true) request.onload = ()=> console.log(request.responseText) request.send()
-
-
必考:這段代碼里的 this 是什么?
- 背代碼
- fn()
this => window/global - obj.fn()
this => obj - fn.call(xx)
this => xx - fn.apply(xx)
this => xx - fn.bind(xx)
this => xx - new Fn()
this => 新的對象 - fn = ()=> {}
this => 外面的 this
- fn()
- 看調用
《this 的值到底是什么?一次說清楚》
- 背代碼
-
必考:閉包/立即執行函數是什么?
- 閉包 https://zhuanlan.zhihu.com/p/22486908 一個函數能訪問這個函數作用域外的變量,那么這個函數和這個變量就叫閉包。
- 立即執行函數 https://zhuanlan.zhihu.com/p/22465092 立即執行函數,聲明一個函數,然后立馬執行。
!function(){alert('我是匿名函數')}()
,他的作用是創建一個獨立的作用域。
var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
liList[i].onclick = function(){
alert(i) // 為什么 alert 出來的總是 6,而不是 0、1、2、3、4、5
}
}
/* 因為 i 是貫穿整個作用域的,而不是給每個 li 分配了一個 i */
var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
!function(ii){
liList[ii].onclick = function(){
alert(ii) // 0、1、2、3、4、5
}
}(i)
}
- 必考:什么是 JSONP,什么是 CORS,什么是跨域?
- JSONP是通過 script 標簽加載數據的方式去獲取數據當做 JS 代碼來執行,提前在頁面上聲明一個函數,函數名通過接口傳參的方式傳給后臺,后臺解析到函數名后在原始數據上「包裹」這個函數名,發送給前端。換句話說,JSONP 需要對應接口的后端的配合才能實現。JSONP不能post,JSONP是通過動態創建script實現的,動態創建script只能用GET
比如:請求方:frank.com 的前端程序員(瀏覽器)
響應方:jack.com 的后端程序員(服務器)
請求方創建 script,src 指向響應方,同時傳一個查詢參數 ?callbackName=yyy
響應方根據查詢參數callbackName,構造形如
yyy.call(undefined, '你要的數據')
yyy('你要的數據')
這樣的響應
瀏覽器接收到響應,就會執行 yyy.call(undefined, '你要的數據')
那么請求方就知道了他要的數據 - CORS 跨域資源共享,它使用額外的 HTTP頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應用被準許訪問來自不同源服務器上的指定的資源。
response.setHeader('Access-Control-Allow-Origin','需要共享的URL')
- 同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互,所以才需要跨域。
- JSONP是通過 script 標簽加載數據的方式去獲取數據當做 JS 代碼來執行,提前在頁面上聲明一個函數,函數名通過接口傳參的方式傳給后臺,后臺解析到函數名后在原始數據上「包裹」這個函數名,發送給前端。換句話說,JSONP 需要對應接口的后端的配合才能實現。JSONP不能post,JSONP是通過動態創建script實現的,動態創建script只能用GET
- 常考:async/await 怎么用,如何捕獲異常?
- 常考:如何實現深拷貝?
背代碼,要點:- 遞歸
- 判斷類型
- 檢查環(也叫循環引用)
- 需要忽略原型
- 常考:如何用正則實現 trim()?
背代碼
```
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '')
}
//或者
function trim(string){
return string.replace(/^\s+|\s+$/g, '')
}
```
常考:不用 class 如何實現繼承?用 class 又如何實現?
-
背代碼,不用 class 這樣實現
function Animal(color){ this.color = color } Animal.prototype.move = function(){} // 動物可以動 function Dog(color, name){ Animal.call(this, color) // 或者 Animal.apply(this, arguments) this.name = name } // 下面三行實現 Dog.prototype.__proto__ = Animal.prototype function temp(){} temp.prototye = Animal.prototype Dog.prototype = new temp() Dog.prototype.constuctor = Dog // 這行看不懂就算了,面試官也不問 Dog.prototype.say = function(){ console.log('汪')} var dog = new Dog('黃色','阿黃')
-
背代碼,用 class 就簡單了
class Animal{ constructor(color){ this.color = color } move(){} } class Dog extends Animal{ constructor(color, name){ super(color) this.name = name } say(){} }
常考:如何實現數組去重?
計數排序變形,背代碼
使用 Set(面試已經禁止這種了,因為太簡單)
使用 WeakMap
放棄:== 相關題目(反著答)
不要背,記不住,太復雜且沒有規律送命題:手寫一個 Promise
提前寫一遍,放在博客里,參考 https://juejin.im/post/5aafe3edf265da238f125c0a