面試

1▲ Vue 中雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理是怎樣的?
vue數(shù)據(jù)雙向綁定的原理是通過數(shù)據(jù)劫持結(jié)合發(fā)布訂閱模式,通過Object.defineProperty方法來(lái)劫持每個(gè)屬性,為每個(gè)屬性添加setter和getter,當(dāng)數(shù)據(jù)變動(dòng)時(shí),發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)
整個(gè)mvvm框架的主要模塊分別為:
1、observer:進(jìn)行數(shù)據(jù)的劫持,get函數(shù)觸發(fā)時(shí),添加訂閱者,set函數(shù)觸發(fā)數(shù)據(jù)watcher,進(jìn)行視圖更新
2、compile:對(duì)元素節(jié)點(diǎn)進(jìn)行掃描和解析,初始化dom,訂閱數(shù)據(jù)變化通知watcher跟新視圖
3、watcher:添加訂閱者,收集屬性變動(dòng),執(zhí)行視圖更新
4、mvvm入口函數(shù)

2vue中的數(shù)據(jù)是如何被渲染的
1、創(chuàng)建實(shí)例,并進(jìn)行初始化,
2、模板編譯(把真實(shí)的dom元素進(jìn)行轉(zhuǎn)換成一個(gè)對(duì)應(yīng)的dom對(duì)象,并描述與數(shù)據(jù)的綁定關(guān)系),生成render函數(shù)(這個(gè)函數(shù)是就構(gòu)建虛擬DOM所需要的工具)
3、對(duì)數(shù)據(jù)進(jìn)行監(jiān)聽,
4、數(shù)據(jù)變化執(zhí)行render函數(shù),生成新的vNode對(duì)象
5、對(duì)比新舊節(jié)點(diǎn),通過diff算法對(duì)節(jié)點(diǎn)進(jìn)行更新,最終編譯成真正的dom結(jié)構(gòu)渲染
3簡(jiǎn)述瀏覽器的渲染過程,重繪和重排在渲染過程中的哪一部分?
瀏覽器進(jìn)程:
browser進(jìn)程:
第三方插件進(jìn)程:
GPU進(jìn)程:
瀏覽器渲染進(jìn)程:瀏覽器內(nèi)核(主要負(fù)責(zé)渲染頁(yè)面,js的執(zhí)行,事件循環(huán)等)
瀏覽器內(nèi)核線程:
GUI渲染線程:負(fù)責(zé)渲染界面,解析html,css,構(gòu)建DOM和renderTree,(互斥)
JS引擎線程:負(fù)責(zé)處理javascript的腳本執(zhí)行,(互斥)
事件觸發(fā)線程:用來(lái)控制事件循環(huán)
定時(shí)觸發(fā)器線程:定時(shí)器和延時(shí)器的所在線程
異步http請(qǐng)求線程:處理http請(qǐng)求
4hash和history
是前端路由的兩種模式,可以記錄當(dāng)前頁(yè)面的狀態(tài),實(shí)現(xiàn)瀏覽器的前進(jìn)和后退
hash:拼在url的尾部,通過#來(lái)拼接,hash值變化不會(huì)導(dǎo)致頁(yè)面發(fā)生請(qǐng)求,對(duì)后端沒有影響,不利于seo
hsitory:可以在url添加參數(shù),利用了h5 的History Interface 中新增的pushState和replaceState方法,特別需要后端的配合,缺點(diǎn)也是刷新可能無(wú)法獲取資源
5Vue 組件間是如何進(jìn)行通信的?
1.父子組件
父-子 props 子-父emit 2.vuex state,mutation,actions,getters modules 3.祖孫組件 provide和inject 允許祖先組件向子孫后代注入一個(gè)依賴,不論層次有多深,只要能夠構(gòu)成上下游的關(guān)系 缺點(diǎn):當(dāng)多個(gè)后代組件同時(shí)依賴同一個(gè)父組件提供數(shù)據(jù)時(shí),只要任一組件對(duì)數(shù)據(jù)進(jìn)行了修改,所有依賴的組件都會(huì) 受到影響,實(shí)際上是增加了耦合度。 任意層級(jí)訪問使數(shù)據(jù)追蹤變的比較困難,你并不能準(zhǔn)確的定位到是哪一個(gè)層級(jí)對(duì)數(shù)據(jù)進(jìn)行了改變,當(dāng)數(shù)據(jù)出現(xiàn)問題時(shí),尤其 是多人協(xié)作時(shí),可能會(huì)大大增加問題定位的損耗。 4.eventBus:全局事件總線 Vue.prototype.EventBus = new Vue() vue的原型上掛載一個(gè)new Vue()
發(fā)送事件:this.eventBus.emit()
接收事件:on() 移除事件:off()

    缺點(diǎn):?jiǎn)雾?yè)面程序刷新會(huì)移除所有的eventbus,當(dāng)前的業(yè)務(wù)可能會(huì)斷裂,所以切記在頁(yè)面銷毀的時(shí)候移除
    原理:它的工作原理是發(fā)布/訂閱方法,通常稱為 Pub/Sub 。兩個(gè)方法$on和$emit。一個(gè)用于創(chuàng)建發(fā)出的事件,它就是$emit;另一個(gè)用于訂閱$on:

6簡(jiǎn)述虛擬 dom 實(shí)現(xiàn)原理,簡(jiǎn)述 diff 算法的實(shí)現(xiàn)機(jī)制和使用場(chǎng)景

虛擬DOM(Virtual DOM) 用js用對(duì)象的方式來(lái)表示Dom結(jié)構(gòu),即,將Dom的變化對(duì)比放在js層

為什么使用虛擬dom:首先頁(yè)面展示需要進(jìn)行對(duì)html和css解析生成對(duì)應(yīng)的dom樹和樣式樹,最后合并生成rendertree,然后布局繪制進(jìn)行展示,
但是在繪制布局過程中,操作js會(huì)導(dǎo)致重排和重繪,這樣就會(huì)導(dǎo)致dom樹的重新渲染,非常消耗性能。
    虛擬dom 就是為了解決這個(gè)問題,首先將dom生成一個(gè)對(duì)象,操作dom先去修改這個(gè)對(duì)象,最后統(tǒng)一完成dom樹的重新構(gòu)建
    所以需要提供轉(zhuǎn)換的方法:dom -> obj   obj -> dom 等方法
diff算法:主要是用來(lái)比較兩棵樹的變化之處,得到一個(gè)發(fā)生變化的節(jié)點(diǎn)列表組成的對(duì)象,正常的時(shí)間復(fù)雜度為O(n*3),但是很少有dom元素跨層級(jí)移動(dòng)的情況,所以,一般是平層比較兩棵樹,時(shí)間復(fù)雜度為O(n),放棄了深度遍歷。
    一般diff需要處理四種情況:
        1、REPLACE : 元素節(jié)點(diǎn)類型發(fā)生變化,
        2、PROPS : 元素節(jié)點(diǎn)類型不變化,屬性或者屬性值發(fā)生變化
        3、TEXT : 文本發(fā)生變化
        4、REORDER : 元素的移動(dòng),包括增加和刪除

7簡(jiǎn)述什么是 XSS 攻擊以及 CSRF 攻擊?
XSS攻擊(Cross Site Scripting)全稱跨站腳本攻擊(讓用戶惡意的執(zhí)行腳本代碼),是一種在web應(yīng)用中的計(jì)算機(jī)安全漏洞,它允許惡意web用戶將代碼植入到提供給其它
用戶使用的頁(yè)面中。
預(yù)防: 對(duì)重要的 cookie設(shè)置 httpOnly, 防止客戶端通過document.cookie讀取 cookie,此 HTTP頭由服務(wù)端設(shè)置。
將不可信的值輸出 URL參數(shù)之前,進(jìn)行 URLEncode操作,而對(duì)于從 URL參數(shù)中獲取值一定要進(jìn)行格式檢測(cè)
CSRF (Cross Site Request Forgery)攻擊,(讓用戶惡意的調(diào)取接口)中文名:跨站請(qǐng)求偽造。其原理是攻擊者構(gòu)造網(wǎng)站后臺(tái)某個(gè)功能接口的請(qǐng)求
地址,誘導(dǎo)用戶去點(diǎn)擊或者用特殊方法讓該請(qǐng)求地址自動(dòng)加載。用戶在登錄狀態(tài)下這個(gè)請(qǐng)求被服務(wù)端接收后會(huì)被誤以為是用
戶合法的操作。對(duì)于 GET 形式的接口地址可輕易被攻擊,對(duì)于 POST 形式的接口地址也不是百分百安全,攻擊者可誘導(dǎo)用
戶進(jìn)入帶 Form 表單可用POST方式提交參數(shù)的頁(yè)面。
目前防御 CSRF 攻擊主要有三種策略:驗(yàn)證 HTTP Referer 字段(referer能夠得到訪問的請(qǐng)求來(lái)源地址);在請(qǐng)求地址中添加 token 并驗(yàn)證;在 HTTP 頭中自定義屬性并驗(yàn)證。
8性能優(yōu)化(重點(diǎn))
了解瀏覽器渲染機(jī)制
1. 解析 HTML 文件,構(gòu)建 DOM 樹,同時(shí)瀏覽器主進(jìn)程負(fù)責(zé)下載 CSS 文件
2. CSS 文件下載完成,解析 CSS 文件成樹形的數(shù)據(jù)結(jié)構(gòu),然后結(jié)合 DOM 樹合并成 RenderObject 樹
3. 布局 RenderObject 樹 (Layout/reflow),負(fù)責(zé) RenderObject 樹中的元素的尺寸,位置等計(jì)算
4. 繪制 RenderObject 樹 (paint),繪制頁(yè)面的像素信息
5. 瀏覽器主進(jìn)程將默認(rèn)的圖層和復(fù)合圖層交給 GPU 進(jìn)程,GPU 進(jìn)程再將各個(gè)圖層合成(composite),最后顯示出頁(yè)面
1、網(wǎng)頁(yè)首頁(yè)渲染減少http請(qǐng)求
2、js會(huì)阻止dom構(gòu)建,可以async
3、操作dom優(yōu)化,減少重排和重繪,重排的操作影響大于重繪,使用框架例如vue,能夠?qū)崿F(xiàn)虛擬dom+diff算法來(lái)優(yōu)化
4、對(duì)于圖片可以使用懶加載
5、事件綁定優(yōu)化:事件委托(減少注冊(cè)時(shí)間,減少內(nèi)存占用)防抖和節(jié)流
6、緩存優(yōu)化
7、vue相關(guān)優(yōu)化:
1、css文件放入單獨(dú)的文件,然后引入
2、組件懶加載
9簡(jiǎn)述 Javascript 原型以及原型鏈
原型是Function上的一個(gè)屬性,它定義了構(gòu)造函數(shù)構(gòu)造出對(duì)象的共有祖先,通過該構(gòu)造函數(shù)構(gòu)造出來(lái)的對(duì)象可以繼承原型的屬性和方法,原型也是對(duì)象
原型鏈,當(dāng)函數(shù)被new操作符操作的時(shí)候,會(huì)創(chuàng)建出一個(gè)對(duì)象,該對(duì)象中有一個(gè)proto屬性指向原型對(duì)象,這樣實(shí)例就可以訪問圓形的屬性和方法,原型也是一個(gè)對(duì)象
所以,原型也是有原型的,因此構(gòu)成了一個(gè)鏈?zhǔn)浇Y(jié)構(gòu),原型鏈的終端是Object.prototype.proto => null
10繼承的常見方式
(1)原型鏈繼承
Child.prototype = new Parent()
特點(diǎn):無(wú)法向父類傳參,繼承單一,所有實(shí)例共享父類實(shí)例屬性
(2)構(gòu)造函數(shù)借用```
Child函數(shù)中:Parent.call(this,params)
特點(diǎn):只能繼承父類屬性,不能繼承父類原型,可以繼承多個(gè)父類
(3)組合繼承
function Child(name) { Person.call(this, name); }
Child.prototype = new Person();
(4)原型式形式
function obj(o){function F(){}; F.prototype = o; return new F()}
let child = obj(new Parent())
特點(diǎn):以函數(shù)返回值來(lái)操作
(5)寄生組合
function obj(o){function F(){}; F.prototype = o; return new F()}
function subObj(o){let f = obj(o); o.name='name'; return o} 這一步可以為實(shí)例傳參
(6)extends
class Child extends Parent{
conscturtor(){
super()
}
}
11 簡(jiǎn)述 Vue 的生命周期
生命周期函數(shù):在vue實(shí)例從創(chuàng)建到銷毀的整個(gè)過程中不同階段的自執(zhí)行函數(shù),
beforeCreate:實(shí)例初始化,但是數(shù)據(jù),事件,Dom等都是undefined
created:數(shù)據(jù)和事件初始化,可以在created函數(shù)中得到
beforeMount:掛載之前,DOM初始化完成,
mounted:完成掛載
beforeUpdate:數(shù)據(jù)更新前的回調(diào),數(shù)據(jù)還未變化
updated:數(shù)據(jù)更新后的回調(diào),數(shù)據(jù)已經(jīng)修改完成
beforeDistory:實(shí)例銷毀之前
distoryed:實(shí)例銷毀之后
activated:keep-alive激活
deactivated:keep-alive組件關(guān)閉
errorCapture:當(dāng)捕獲到子孫組件的錯(cuò)誤時(shí)觸發(fā)

12 簡(jiǎn)述瀏覽器的緩存機(jī)制
首先,瀏覽器和服務(wù)器之間的通信方式為應(yīng)答模式,即,瀏覽器發(fā)起http請(qǐng)求-服務(wù)器響應(yīng)請(qǐng)求,
發(fā)起請(qǐng)求,先去緩存中查看,緩存中沒有發(fā)起http請(qǐng)求服務(wù)器,拿到響應(yīng)數(shù)據(jù),并根據(jù)詳情數(shù)據(jù)的緩存規(guī)則,決定是否進(jìn)行緩存,
將具有緩存標(biāo)識(shí)的數(shù)據(jù)存入瀏覽器緩存
根據(jù)是否需要向服務(wù)器重新發(fā)起http請(qǐng)求,將緩存過程分為兩個(gè)部分,分別是強(qiáng)緩存和協(xié)商緩存
強(qiáng)緩存:不會(huì)向服務(wù)器發(fā)送請(qǐng)求,直接從緩存中取 控制強(qiáng)制緩存的字段分別是Expires和Cache-Control,其中Cache-Conctrol的優(yōu)先級(jí)比Expires高。
(1)public:所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)
(2)private:所有內(nèi)容只有客戶端可以緩存,Cache-Control的默認(rèn)取值
(3)no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過協(xié)商緩存來(lái)驗(yàn)證決定
(4)no-store:所有內(nèi)容都不會(huì)被緩存,即不使用強(qiáng)制緩存,也不使用協(xié)商緩存
(5)max-age=xxx (xxx is numeric):緩存內(nèi)容將在xxx秒后失效
協(xié)商緩存:強(qiáng)緩存失效,瀏覽器攜帶緩存向服務(wù)器發(fā)起請(qǐng)求,由服務(wù)器更具緩存表示決定是否使用緩存的過程(eTag,信息的過期標(biāo)識(shí)) 控制協(xié)商緩存的字段分別有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的優(yōu)先級(jí)比Last-Modified / If-Modified-Since高。

13 簡(jiǎn)述虛擬 dom 實(shí)現(xiàn)原理,簡(jiǎn)述 diff 算法的實(shí)現(xiàn)機(jī)制和使用場(chǎng)景

虛擬DOM(Virtual DOM) 用js用對(duì)象的方式來(lái)表示Dom結(jié)構(gòu),即,將Dom的變化對(duì)比放在js層

為什么使用虛擬dom:首先頁(yè)面展示需要進(jìn)行對(duì)html和css解析生成對(duì)應(yīng)的dom樹和樣式樹,最后合并生成rendertree,然后布局繪制進(jìn)行展示,
但是在繪制布局過程中,操作js會(huì)導(dǎo)致重排和重繪,這樣就會(huì)導(dǎo)致dom樹的重新渲染,非常消耗性能。
    虛擬dom 就是為了解決這個(gè)問題,首先將dom生成一個(gè)對(duì)象,操作dom先去修改這個(gè)對(duì)象,最后統(tǒng)一完成dom樹的重新構(gòu)建
    所以需要提供轉(zhuǎn)換的方法:dom -> obj   obj -> dom 等方法
diff算法:主要是用來(lái)比較兩棵樹的變化之處,得到一個(gè)發(fā)生變化的節(jié)點(diǎn)列表組成的對(duì)象,正常的時(shí)間復(fù)雜度為O(n*3),但是很少有dom元素跨層級(jí)移動(dòng)的情況,所以,一般是平層比較兩棵樹,時(shí)間復(fù)雜度為O(n),放棄了深度遍歷。
    一般diff需要處理四種情況:
        1、REPLACE : 元素節(jié)點(diǎn)類型發(fā)生變化,
        2、PROPS : 元素節(jié)點(diǎn)類型不變化,屬性或者屬性值發(fā)生變化
        3、TEXT : 文本發(fā)生變化
        4、REORDER : 元素的移動(dòng),包括增加和刪除

14 簡(jiǎn)述 Javascript 中的防抖與節(jié)流的原理并嘗試實(shí)現(xiàn)
防抖:持續(xù)操作,只會(huì)執(zhí)行最后一次回調(diào)
思想:維護(hù)一個(gè)timer,只要執(zhí)行,我就先清空在賦值,讓他重新開始計(jì)時(shí),直到最后一次觸發(fā)成功
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持續(xù)觸發(fā),那么就清除定時(shí)器,定時(shí)器的回調(diào)就不會(huì)執(zhí)行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
節(jié)流:只需操作,按時(shí)執(zhí)行
思想:維護(hù)一個(gè)flag開關(guān),狀態(tài)是開,執(zhí)行過程中關(guān)閉,執(zhí)行完再打開
function throttle(func,delay){
let run = true
return function () {
if(!run){
return
}
run = false
setTimeout(()=>{
func.apply(this,arguments)
run = true
},delay)
}
}

15 什么是閉包,什么是立即執(zhí)行函數(shù),它的作用是什么?簡(jiǎn)單說(shuō)一下閉包的使用場(chǎng)景
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的橋梁。
閉包可以實(shí)現(xiàn)防抖和節(jié)流,可以做緩存(維護(hù)一個(gè)變量的狀態(tài)),可以防止命名沖突,
閉包會(huì)導(dǎo)致私有變量無(wú)法被銷毀,造成內(nèi)存大量消耗,導(dǎo)致內(nèi)存泄露,閉包需要突破作用域連,會(huì)造成性能問題

16 簡(jiǎn)述瀏覽題事件循環(huán)機(jī)制
js是單線程執(zhí)行的,js中的執(zhí)行代碼分為同步任務(wù)和異步任務(wù),
需要一個(gè)規(guī)則來(lái)規(guī)定他們的執(zhí)行順序
首先,js引擎執(zhí)行代碼會(huì)先執(zhí)行同步代碼,會(huì)把異步任務(wù)掛起,直到同步任務(wù)執(zhí)行完,異步任務(wù)執(zhí)行完后會(huì)放到事件隊(duì)列中,(異步事件中分為宏任務(wù)和微任務(wù),先執(zhí)行微任務(wù)隊(duì)列,后執(zhí)行宏任務(wù)隊(duì)列)直到執(zhí)行棧為空,然后執(zhí)行微任務(wù)隊(duì)列,再然后執(zhí)行宏任務(wù),判斷宏任務(wù)中是否有同步代碼和微任務(wù),就按照這個(gè)規(guī)則來(lái)執(zhí)行任務(wù)。
當(dāng)前執(zhí)行棧執(zhí)行完畢時(shí)會(huì)立刻先處理所有微任務(wù)隊(duì)列中的事件,然后再去宏任務(wù)隊(duì)列中取出一個(gè)事件。同一次事件循環(huán)中,微任務(wù)永遠(yuǎn)在宏任務(wù)之前執(zhí)行。
宏任務(wù):settimeout setinterval setimmediate I/O UI渲染

微任務(wù):promise process.nextTick  Object.observe(已經(jīng)被廢棄,異步的監(jiān)視一個(gè)對(duì)象的修改)

17 localstorage 與 cookie 的區(qū)別是什么?
cookie并不適合存儲(chǔ),主要是用來(lái)存一些身份標(biāo)識(shí),在請(qǐng)求接口的時(shí)候附帶上這些cookie,cookie需要進(jìn)行封裝,大小為4k,不同瀏覽器對(duì)個(gè)數(shù)有限制,每次請(qǐng)求都會(huì)附帶,影響效率,可以對(duì)cookie屬性Max Age(失效日期)domian和path(限制 cookie 能被哪些 URL 訪問)
web storage 用來(lái)本地存儲(chǔ)
session 一次會(huì)話
local 永久
18 promise 有哪些狀態(tài)?簡(jiǎn)述 promise.all 的實(shí)現(xiàn)原理
19 簡(jiǎn)述 CORS 的用途以及基本設(shè)置 什么是跨域,什么情況下會(huì)發(fā)生跨域請(qǐng)求?
Cross-origin Resource Sharing 中文名稱 “跨域資源共享” 簡(jiǎn)稱 “CORS”,它突破了一個(gè)請(qǐng)求在瀏覽器發(fā)出只能在同源的情況下向服務(wù)器獲取數(shù)據(jù)的限制
原因:瀏覽器限制了從腳本內(nèi)發(fā)起的跨源 HTTP 請(qǐng)求(協(xié)議、域名、端口號(hào))同源策略
解決方法:
JSONP:原理就是在 script 標(biāo)簽里面加載了一個(gè)鏈接請(qǐng)求,去訪問服務(wù)器的某個(gè)請(qǐng)求,返回內(nèi)容。
CORS: 簡(jiǎn)單請(qǐng)求和預(yù)檢請(qǐng)求,當(dāng)使用XMLHttpRequest發(fā)送請(qǐng)求時(shí),瀏覽器發(fā)現(xiàn)該請(qǐng)求不符合同源策略,會(huì)給該請(qǐng)求加一個(gè)請(qǐng)求頭:Origin,后臺(tái)進(jìn)行一系列處理,如果確定接受請(qǐng)求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin;
前端本地代理:服務(wù)器沒有跨域的概念,在配置文件中設(shè)置代理,

20 簡(jiǎn)述 JWT 的原理和校驗(yàn)機(jī)制
JSON Web Token(簡(jiǎn)稱 JWT)是目前最流行的跨域認(rèn)證解決方案。
類似token,用戶登錄后獲得后端返回的jwt,在請(qǐng)求資源的時(shí)候附加到請(qǐng)求頭的Authorization
ck▲ 25 手寫題庫(kù) https://github.com/Mayandev/fe-interview-handwrite
實(shí)現(xiàn)bind
Function.prototype.newBind = function(context,...args){
return (...newArgs) => this.apply(context,[...args,...newArgs])
}
+實(shí)現(xiàn)apply
Function.prototype.newApply = function(context,args){
context.fn = this
return context.fn(...args)
}
+實(shí)現(xiàn)call
Function.prototype.newCall = function (context,...args){
context.fn = this
return context.fn(...args)
}

▲ 8 簡(jiǎn)述 CSS 有哪些上下文類型?
層疊上下文:定位元素 > 內(nèi)聯(lián)元素 > 浮動(dòng)元素 > 塊級(jí)元素

js預(yù)編譯流程
1、語(yǔ)法解析:檢查代碼有沒有低級(jí)錯(cuò)誤,
2、預(yù)編譯:代碼執(zhí)行前,大部分是在函數(shù)執(zhí)行前
3、解釋執(zhí)行:執(zhí)行

預(yù)編譯:
    創(chuàng)建GO,變量提升,函數(shù)提升
    
    創(chuàng)建AO,形參,變量,賦值undefined;形參實(shí)參統(tǒng)一;函數(shù)提升

Object.defineProterty 和 Proxy區(qū)別
可配置,可賦值,可枚舉,value,set,get
雖然Object.defineProperty能夠劫持對(duì)象的屬性,但是需要對(duì)對(duì)象的每一個(gè)屬性進(jìn)行遍歷劫持;如果對(duì)象上有新增的屬性,則需要對(duì)新增的屬性再次進(jìn)行劫持;如果屬性是對(duì)象,還需要深度遍歷。這也是為什么Vue給對(duì)象新增屬性需要通過$set的原因,其原理也是通過Object.defineProperty對(duì)新增的屬性再次進(jìn)行劫持。

相較于Object.defineProperty劫持某個(gè)屬性,Proxy則更徹底,不在局限某個(gè)屬性,而是直接對(duì)整個(gè)對(duì)象進(jìn)行代理,Proxy不僅能夠監(jiān)聽到屬性的增加,還能監(jiān)聽屬性的刪除,比Object.defineProperty的功能更為強(qiáng)大

vue-router原理
不同路徑展示不同資源
hash:hashchange來(lái)實(shí)現(xiàn)更新頁(yè)面部分內(nèi)容的操作
for...in for...of
for in 一般是遍歷數(shù)組或?qū)ο蟮膋ey值
for of 一般是遍歷數(shù)組的value,通常能夠遍歷有iterator方法的結(jié)構(gòu)

▲ 5 簡(jiǎn)述 ES6 的新特性
let,const
symbol
set,map
字符串,數(shù)組,對(duì)象新增方法
解構(gòu)賦值
三點(diǎn)運(yùn)算符
形參默認(rèn)值
proxy
class
promise
gen
async/await

▲ 5 了解過 Gulp Grunt 嗎?簡(jiǎn)述他們的優(yōu)勢(shì)以及劣勢(shì)
▲ 4 Javascript 可以保存的最大數(shù)值是多少?
number類型的數(shù)據(jù)在計(jì)算機(jī)中是以IEEE754雙精度存儲(chǔ)的,但是在二進(jìn)制存儲(chǔ)的時(shí)候,會(huì)損失一部分精度
Number.MAX_VALUE
Number.MAX_SAFE_INTEGER 最大安全整數(shù) 2^53 -1
▲ 4 優(yōu)化首屏渲染的方式有哪幾種?
按需加載模塊或者組件
路由懶加載
npx vue-cli-service build --report 可以產(chǎn)看打包各個(gè)模塊的體積情況,從而針對(duì)性的去修改
圖片懶加載
減少http請(qǐng)求和dom數(shù)量
▲ 3 JavaScript 中的嚴(yán)格模式是什么,有什么作用?
是一種規(guī)范js書寫與語(yǔ)法規(guī)范限制的一種標(biāo)準(zhǔn)
eval()
with()
arguments.callee:正在被執(zhí)行的函數(shù)
fun.caller:
變量聲明重復(fù)
預(yù)編譯this指向undefined
▲ 11 簡(jiǎn)述項(xiàng)目打包和發(fā)布的流程
▲ 7 簡(jiǎn)述瀏覽器的垃圾回收機(jī)制
1.標(biāo)記清除:當(dāng)變量進(jìn)入環(huán)境時(shí),將變量標(biāo)記"進(jìn)入環(huán)境",當(dāng)變量離開環(huán)境時(shí),標(biāo)記為:"離開環(huán)境"。某一個(gè)時(shí)刻,垃圾回收器會(huì)過濾掉環(huán)境中的變量,以及被環(huán)境變量引用的變量,剩下的就是被視為準(zhǔn)備回收的變量。
2.引用計(jì)數(shù):判斷當(dāng)前變量被引用的次數(shù),判斷這個(gè)變量地址被引用的次數(shù),當(dāng)被引用次數(shù)變?yōu)?,那么就會(huì)被回收
▲ 7 移動(dòng)端適配有哪些方案?
▲ 6 MVC 模型和 MVVM 模型的區(qū)別
▲ 12 簡(jiǎn)述輸入 URL 到瀏覽器顯示的流程
url->判斷是否有緩存,有緩存則去緩存中取
>域名解析器->ip地址->對(duì)應(yīng)的資源服務(wù)器 ->
▲ 12 預(yù)編譯
▲ 10 簡(jiǎn)述 Javascript 中 this 的指向有哪些

this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰(shuí),實(shí)際上this的最終指向的是那個(gè)調(diào)用它的對(duì)象
this的作用范圍在于函數(shù),和對(duì)象沒有關(guān)系
this只會(huì)指向調(diào)用者,o.b.fn() 指向o.b
new會(huì)改變this指向,如果返回引用值類型{},[],fn,this就會(huì)指向返回值,如果返回值是原始值,就會(huì)指向?qū)嵗?箭頭函數(shù)的
函數(shù)定義時(shí)的this

▲ 9 簡(jiǎn)述 jsonp 的工作原理
Script 標(biāo)簽本身的功能就是異步加載js并且會(huì)以js的方式解析執(zhí)行。一旦在script的標(biāo)簽里加入src的屬性,瀏覽器執(zhí)行到這個(gè)標(biāo)簽時(shí)就回去 請(qǐng)求指定的地址,如果服務(wù)器返回的是js格式的代碼,甚至可以是js的函數(shù),只要是能被js解析的,都可以被執(zhí)行,這也就是jsonp的原理
▲ 9 簡(jiǎn)述 Javascript 事件冒泡和事件捕獲原理
冒泡:即事件開始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)
▲ 8 如何解決 CSS 類名重名?
1.人為規(guī)定
2.作用域scoped
▲ 8 簡(jiǎn)述發(fā)布訂閱模式的實(shí)現(xiàn)方式以及原理
▲ 8 箭頭函數(shù)和普通函數(shù)的區(qū)別是什么?
1.箭頭函數(shù)不能夠當(dāng)做構(gòu)造函數(shù),不能new操作
2.箭頭函數(shù)沒有arguments
3.箭頭函數(shù)沒有自己的this,只會(huì)捕獲上下文中的this作為自己的this,該函數(shù)定義時(shí)所在的this(不是執(zhí)行)
4.箭頭函數(shù)無(wú)法改變this指向
5.箭頭函數(shù)沒有原型
6.普通函數(shù)this指向調(diào)用者
▲ 7 簡(jiǎn)述常見異步編程方案 (promise, generator, async) 的原理
Promise 為我們解決了什么問題?在傳統(tǒng)的異步編程中,如果異步之間存在依賴關(guān)系,就需要通過層層嵌套回調(diào)的方式滿足
這種依賴,如果嵌套層數(shù)過多,可讀性和可以維護(hù)性都會(huì)變得很差,產(chǎn)生所謂的“回調(diào)地獄”,而 Promise 將嵌套調(diào)用改為鏈
式調(diào)用,增加了可閱讀性和可維護(hù)性。
▲ 6 簡(jiǎn)述 Javascript 的柯里化與逆柯里化
柯里化其實(shí)是函數(shù)式編程的一個(gè)過程,在這個(gè)過程中我們能把一個(gè)帶有多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換成一系列的嵌套函數(shù)。它返回一個(gè)新函數(shù),這個(gè)新函數(shù)期望傳入下一個(gè)參數(shù)
優(yōu)點(diǎn): 可以輕松的重用和配置
避免調(diào)用相同參數(shù)的函數(shù)
▲ 6 簡(jiǎn)述常見的 HTTP 狀態(tài)碼的含義(301,304,401,403)
301:永久重定向
302:臨時(shí)重定向
304:請(qǐng)求未修改
400:客戶端錯(cuò)誤
401:沒有訪問權(quán),需要認(rèn)證
403:服務(wù)端拒絕執(zhí)行請(qǐng)求
404:請(qǐng)求資源未找到
▲ 4 數(shù)組去重有哪些方式?手寫數(shù)組去重
set容器,對(duì)象key值方法,indexOf,for*2
▲ 4 Vue 組件間是如何進(jìn)行通信的?
1.父子組件
父-子 props 子-父emit 2.vuex state,mutation,actions,getters modules 3.祖孫組件 provide和inject 允許祖先組件向子孫后代注入一個(gè)依賴,不論層次有多深,只要能夠構(gòu)成上下游的關(guān)系 缺點(diǎn):當(dāng)多個(gè)后代組件同時(shí)依賴同一個(gè)父組件提供數(shù)據(jù)時(shí),只要任一組件對(duì)數(shù)據(jù)進(jìn)行了修改,所有依賴的組件都會(huì) 受到影響,實(shí)際上是增加了耦合度。 任意層級(jí)訪問使數(shù)據(jù)追蹤變的比較困難,你并不能準(zhǔn)確的定位到是哪一個(gè)層級(jí)對(duì)數(shù)據(jù)進(jìn)行了改變,當(dāng)數(shù)據(jù)出現(xiàn)問題時(shí),尤其 是多人協(xié)作時(shí),可能會(huì)大大增加問題定位的損耗。 4.eventBus:全局事件總線 Vue.prototype.EventBus = new Vue() vue的原型上掛載一個(gè)new Vue()
發(fā)送事件:this.eventBus.emit()
接收事件:on() 移除事件:off()

    缺點(diǎn):?jiǎn)雾?yè)面程序刷新會(huì)移除所有的eventbus,當(dāng)前的業(yè)務(wù)可能會(huì)斷裂,所以切記在頁(yè)面銷毀的時(shí)候移除
    原理:它的工作原理是發(fā)布/訂閱方法,通常稱為 Pub/Sub 。兩個(gè)方法$on和$emit。一個(gè)用于創(chuàng)建發(fā)出的事件,它就是$emit;另一個(gè)用于訂閱$on:

▲ 2 CSS3 有哪些新特性
邊框圓角,邊框圖片,flex布局,偽類,漸變背景,動(dòng)畫
▲ 2 CSS 的 position 常用值有哪些,有什么區(qū)別?
relative
absolute
static
fixed
inherit
▲ 1 CSS3 如何實(shí)現(xiàn)漸變色?
background-image: linear-gradient(angle, color-stop1, color-stop2);
background-image: radial-gradient(shape size at position, start-color, ..., last-color);
▲ 1 flex 常用的屬性有哪些?flex: 1 1 0 是什么意思?
父元素{
flex-flow:
flex-direction:row,row-reverse,cloumn,cloumn-reverse
flex-wrap : wrap , nowrap , wrap-reverse
jusitfy-content : flex-start,flex-end,center,
space-betwwen(兩邊沒有空隙),space-around(兩邊有空隙)
align-items:flex-start,flex-end,center,baseline,stretch
align-content(控制多行在豎直方向上的對(duì)齊方式,只有一行的話不會(huì)起作用):
flex-start,flex-end,center,stretch,space-between,space-around
}
子元素{
order:
flex{
flex-grow:0,有剩余空間,按照各個(gè)值的比例分配剩余空間
flex-shirk:1 沒有剩余空間,所有item都會(huì)縮小,設(shè)置縮小的比例,0表示不縮小,不能為負(fù)值
flex-basis:auto,對(duì)item設(shè)置特定的寬高,
}
align-self: 某一個(gè)item豎直方向上的對(duì)齊方式,
}
▲ 1 如何實(shí)現(xiàn) div 元素水平垂直居中
1.flex布局
2.子絕父相,letf50% margin-1/2width(tansform:translate(-50%,50%)
3..........四邊0
▲ 1 什么情況下 z-index 不生效?
只有定位的元素(即position屬性值不是static的元素)的z-index才會(huì)起作用。
▲ 8 簡(jiǎn)述 Javascript 的數(shù)據(jù)類型
原始值:String Boolean Number null undefined
引用值:Array Object Function
▲ 7 簡(jiǎn)述 webpack 的打包流程
webpack是模塊打包器,主要是分析各個(gè)模塊的的依賴關(guān)系,把復(fù)雜的文件依賴打包成單獨(dú)的文件,并且可以把高級(jí)語(yǔ)法轉(zhuǎn)化成瀏覽器可以識(shí)別的語(yǔ)法
1、安裝babel的一系列插件
2、函數(shù)1:讀取文件信息,并獲取當(dāng)前js文件的依賴關(guān)系:會(huì)返回下面的數(shù)據(jù)結(jié)構(gòu),這里包括了模塊的id,文件路徑,依賴數(shù)組(entry.js依賴了message.js,所以會(huì)返回依賴的文件名)
3、函數(shù)2:從入口開始分析所有的依賴,形成依賴圖,采用廣度遍歷:遍歷函數(shù)的依賴文件數(shù)組
4、函數(shù)3:根據(jù)生成的依賴關(guān)系圖,生成瀏覽器可以執(zhí)行的文件:處理模塊關(guān)系數(shù)組,

▲ 6 簡(jiǎn)述 CSS 盒模型
標(biāo)準(zhǔn)盒模型:margin border padding content(width只有content)
IE盒模型:width包括 border + padding + content
可以通過box-sizing:border-box(IE)
content-box(默認(rèn))
▲ 4 rem 與 em 的區(qū)別以及使用場(chǎng)景
谷歌瀏覽器默認(rèn)最小的font-size是12px,低于12的默認(rèn)展示12px
em:首先會(huì)依據(jù)當(dāng)前元素的font-size為基準(zhǔn),無(wú)論單位是什么,只要有fontsize屬性,如果沒有則相對(duì)于父元素的單位。
rem:會(huì)根據(jù)根元素為標(biāo)準(zhǔn)(html默認(rèn)fontsize為16px)
▲ 3 const, let, var 關(guān)鍵字有什么區(qū)別?
1、變量提升
2.作用域,暫時(shí)性死區(qū)
3.const定義變量的地址不能被修改
▲ 9 readyState 的不同返回值有什么區(qū)別?
0:表示未初始化,1表示服務(wù)器連接已經(jīng)建立,2表示正在發(fā)送請(qǐng)求,3表示正在處理請(qǐng)求,4表示請(qǐng)求結(jié)束完成響應(yīng)
let xhr = new XMLHttpRequest
xhr.open(httpMethos,url,isAsync)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200)
m = xhr.responseText
}
xhr.send()
▲ 2 實(shí)現(xiàn)三欄布局
1、float布局:左側(cè)左浮動(dòng),右側(cè)右浮動(dòng),中間margin左右
2、position布局:左側(cè)left0,右側(cè)right0,中間left左寬,right右寬
3、flex布局
▲ 1 正則表達(dá)式 /w 是什么意思?
看看
▲ 1 什么是可繼承元素和不可繼承元素?
font,font-size,color,text-align,line-height,font-family,

**nextTick**extTick 是在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào),在修改數(shù)據(jù)之后使用
$nextTick,則可以在回調(diào)中獲取更新后的 DOM
computed和methods
執(zhí)行結(jié)果相同
computed: 計(jì)算屬性是基于它們的依賴進(jìn)行緩存的,只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值
method ,只要發(fā)生重新渲染,method 調(diào)用總會(huì)執(zhí)行該函數(shù)
keep-alive

include:字符串或者正則表達(dá)式,匹配成功的會(huì)被緩存
exclude:字符串或者正則表達(dá)式,匹配成功的不會(huì)被緩存
是vue內(nèi)置的一個(gè)組件,可以使被包含的組件保留狀態(tài)或是避免重新渲染

for循環(huán)的key
主要用在vue的虛擬Dom算法上,用于識(shí)別新舊節(jié)點(diǎn), 當(dāng)數(shù)據(jù)變化后,可以最大程度的識(shí)別新增或者減少的節(jié)點(diǎn),實(shí)現(xiàn)高效的更新
·····································································
BFC的理解,
display:inline-block
float
overflow:!visiable
position:absolute、fixed

選擇器,層級(jí)上下文,
自適應(yīng)布局rem原理(如何兼容不同手機(jī)dpi),
font-size 10px如何實(shí)現(xiàn)、
縮放
移動(dòng)端一像素
旋轉(zhuǎn)
媒體查詢

js為什么需要放在body(更好的回答其實(shí)是瀏覽器的渲染引擎和js解析引擎的沖突,當(dāng)然回答js是單線程執(zhí)行也沒問題,如何優(yōu)化)?
操作DOM為什么是昂貴的?
操作dom,會(huì)出發(fā)頁(yè)面進(jìn)行重繪和重排,這些操作會(huì)嚴(yán)重影響瀏覽器的渲染性能,
優(yōu)秀的框架:vue的虛擬dom和diff算法
事件委托

oop編程?
oop:面向?qū)ο缶幊蹋ㄓ?jì)算機(jī)編程架構(gòu)):三大基本特性:封裝,繼承,多態(tài)
注重對(duì)象,當(dāng)解決一個(gè)問題的時(shí)候,面向?qū)ο髸?huì)把事物抽象成對(duì)象的概念,就是說(shuō)這個(gè)問題里面有哪些對(duì)象,然后給對(duì)象賦一些屬性和方法,然后讓每個(gè)對(duì)象去執(zhí)行自己的方法,問題得到解決。
面向過程:注重過程的。當(dāng)解決一個(gè)問題的時(shí)候,面向過程會(huì)把事情拆分成: 一個(gè)個(gè)函數(shù)和數(shù)據(jù)(用于方法的參數(shù)) 。然后按照一定的順序,執(zhí)行完這些方法(每個(gè)方法看作一個(gè)過程),等方法執(zhí)行完了,事情就搞定了。

js深拷貝?(JSON方法實(shí)現(xiàn)拷貝有什么問題?)
1、原生遞歸方式:deepClone
2、JSON轉(zhuǎn)換,不能對(duì)函數(shù)和一些特殊的對(duì)象進(jìn)行處理
3、Object.assign(),只能對(duì)一級(jí)進(jìn)行克隆,二級(jí)不會(huì)克隆,Object.assign({},target)
————————————————————————————————————————————————————————————————————————
數(shù)組亂序-洗牌算法
1、洗牌算法:從數(shù)組末位置開始計(jì)算,找到一個(gè)隨機(jī)的位置進(jìn)行位置互換,循環(huán)操作
2、sort(function(){ return .5-Math.random()}) a-b>0升序,反之降序 不同瀏覽器的js引擎對(duì)sort方法實(shí)現(xiàn)算法不一樣,有冒泡,快排,插入排序
手動(dòng)實(shí)現(xiàn)instanceof
function _instanceof(L,R){
let _R = R.prototype
while(true){
L = L.proto
if(L === null){
return false
}
if(L === _R){
return true
}
}
}

vue路由守衛(wèi)
全局:beforeEach,beforeResolve,afterEach
路由獨(dú)享:beforeEnter
組件:beforeRouteEnter、beforeRouteUpdate (2.2+)、beforeRouteLeave三個(gè)
vuex 和 全局變量的區(qū)別
1、響應(yīng)式
2、修改狀態(tài)的方式
3、命名沖突


node常用模塊
http:用來(lái)創(chuàng)建服務(wù)器
path:常用來(lái)處理文件路徑,通過path上的api可以路徑信息上的參數(shù),除此之外也有很多方法來(lái)解決實(shí)際遇到的問題,拼接和容錯(cuò)處理
fs:處理文件,對(duì)文文件進(jìn)行讀取和操作
url:對(duì)地址進(jìn)行操作
events:對(duì)事件進(jìn)行處理,監(jiān)聽,移除 發(fā)出等操作

webpack中l(wèi)oder和plugin區(qū)別
loader 用于加載某些資源文件。 因?yàn)閣ebpack 本身只能打包c(diǎn)ommonjs規(guī)范的js文件,對(duì)于其他資源例如 css,圖片,或者其他的語(yǔ)法集,比如 jsx, coffee,是沒有辦法加載的。 這就需要對(duì)應(yīng)的loader將資源轉(zhuǎn)化,加載進(jìn)來(lái)。從字面意思也能看出,loader是用于加載的,它作用于一個(gè)個(gè)文件上。

對(duì)于plugin,它就是一個(gè)擴(kuò)展器,它豐富了wepack本身,針對(duì)是loader結(jié)束后,webpack打包的整個(gè)過程,它并不直接操作文件內(nèi)容,而是基于事件機(jī)制工作,會(huì)監(jiān)聽webpack打包過程中的某些節(jié)點(diǎn)

面試題:
webpack中常用的loader和plugin
判斷對(duì)象或者是數(shù)組
判斷是一個(gè)空對(duì)象
兩個(gè)字符串的最短相同子串

didi

css選擇第二個(gè)a標(biāo)簽 (元素,類,id,屬性,派生) li:nth-child(3){background:#090} nth-last-of-type() 作用類似,但是僅匹配使用同種標(biāo)簽的元素 input[type="text"]
bfc: display float overflow position
設(shè)計(jì)一個(gè)抽獎(jiǎng)系統(tǒng)
typeof instanceof(一個(gè)對(duì)象的原型鏈上是否存在另一個(gè)對(duì)象的原型) 返回值不一樣,
diff
數(shù)組扁平化 reduce遞歸 循環(huán)遞歸 while三點(diǎn)運(yùn)算符 Array.flat
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
手寫promise
js單線程? 作為瀏覽器腳本語(yǔ)言,JavaScript 的主要用途是與用戶互動(dòng),以及操作 DOM。這決定了它只能是單線程,
觀察者模式
saas

二叉樹

冒泡,排序的算法
webpack相關(guān)
vue的filters
動(dòng)態(tài)規(guī)劃
字符串模板的方法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容