記錄下我遇到過的前端面試題 (一)
(一)簡述Vue的雙向綁定:
????????最近的項目基本都是基于Vue進行開發(fā)的疆偿,但是卻對Vue的雙向綁定原理理解的馬馬虎虎鄙皇。被面試到這個問題的時候播玖,我的回答是:基于Object.defineProperty()這個核心方法褐奥,并且通過這個方法的setter和getter對數(shù)據(jù)進行劫持監(jiān)聽和設(shè)置新值肤寝。當(dāng)被問到能再詳細點嗎,就傻眼了(自由發(fā)揮抖僵。鲤看。。)耍群。
鑒于此义桂,雖然不求完全吃透,但是用了這么久蹈垢,起碼雙向綁定的實現(xiàn)邏輯得能簡述出來慷吊。
Vue數(shù)據(jù)雙向綁定原理
采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter曹抬,getter溉瓶,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。此時實現(xiàn)過程涉及3個非常重要的東東:Observer堰酿、Watcher疾宏、Compile。
Observer: 一個數(shù)據(jù)監(jiān)聽器触创,首先是通過遞歸方法遍歷所有的屬性值坎藐,并且使用Object.defineProperty( )來對值進行劫持綁定。
Watcher:一個訂閱者哼绑,用于接收Observer發(fā)來的更新信息岩馍,并且執(zhí)行相應(yīng)的更新回調(diào)。
Compile:對每個元素節(jié)點的指令進行掃描和解析抖韩,根據(jù)指令模板替換數(shù)據(jù)蛀恩,以及綁定相應(yīng)的更新函數(shù)
實現(xiàn)過程:
首先數(shù)據(jù)監(jiān)聽器Observer,能夠?qū)?shù)據(jù)對象的所有屬性進行監(jiān)聽茂浮,如有變動可拿到最新值并通知訂閱者Watcher双谆。Watcher連接Observer和Compile的橋梁,能夠訂閱并收到每個屬性變動的通知励稳,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù)佃乘,從而更新視圖。
(二)說說瀏覽器渲染過程:
? ? ? ? 當(dāng)時碰到這個問題的時候也是挺懵逼的驹尼,因為不太清楚問的是哪個過程趣避。那么這邊就以頁面生成的過程作為問題。我記得我當(dāng)時的回答是:首頁HTML生成好DOM樹新翎,然后CSS規(guī)則生成樹程帕,接著結(jié)合HTML樹和CSS規(guī)則樹布局。嗯嗯地啰,渣渣的問答愁拭。
具體渲染過程:
1. 解析HTML生成DOM樹。
2. 解析CSS生成CSSOM規(guī)則樹亏吝。
3. 將DOM樹與CSSOM規(guī)則樹合并在一起生成渲染樹岭埠。
4. 遍歷渲染樹開始布局,計算每個節(jié)點的位置大小信息蔚鸥。
5. 將渲染樹每個節(jié)點繪制到屏幕惜论。
注意的是:
1. 渲染過程會碰到渲染阻塞。也就是當(dāng)瀏覽器遇到一個 script 標記時止喷,DOM 構(gòu)建將暫停馆类,直至腳本完成執(zhí)行,然后繼續(xù)構(gòu)建DOM弹谁。每次去執(zhí)行JavaScript腳本都會嚴重地阻塞DOM樹的構(gòu)建乾巧,如果JavaScript腳本還操作了CSSOM句喜,而正好這個CSSOM還沒有下載和構(gòu)建,瀏覽器甚至?xí)舆t腳本執(zhí)行和構(gòu)建DOM沟于,直至完成其CSSOM的下載和構(gòu)建咳胃。
2.?CSS 優(yōu)先:引入順序上,CSS 資源先于 JavaScript 資源社裆; JS置后:我們通常把JS代碼放到頁面底部拙绊,且JavaScript 應(yīng)盡量少影響 DOM 的構(gòu)建向图。
(三)實現(xiàn)一個滾動型的無限加載數(shù)據(jù)組件:
? ? ? ? 當(dāng)時回答的實現(xiàn)邏輯是有2種:
? ? ? ? ?(1) 首先請求前2頁的數(shù)據(jù)泳秀,然后給滾動條綁定一個滾動事件,監(jiān)聽滾動條滾動距離榄攀,當(dāng)滾動條滾動到離底部還有一定的距離的時候馬上請求下一頁的數(shù)據(jù)嗜傅。(記得解綁事件)
? ? ? ? ?(2) 首先請求前2頁的數(shù)據(jù),然后添加一個定時器函數(shù)檩赢,每隔0.5s監(jiān)聽當(dāng)前瀏覽器高度吕嘀,當(dāng)滾動條高度離底部還有一定的距離的時候馬上請求下一頁的數(shù)據(jù)。(記得清楚定時器)
? ? ? ? 如果還有其他更好的辦法贞瞒,麻煩指教下哈哈哈偶房。
(四)CSS垂直居中方式:
? ? 面試的時候好像回答出了好幾個,也沒回答全部军浆。不過當(dāng)時是被面試人員像擠奶一樣擠出來的棕洋,面試員就一句:還有嗎?
????那就重新整理下:
? ? (1)文本居中用line-height乒融;
? ? (2)vertical-align屬性掰盘;
? ? (3)display:table (或者:+?vertical-align);
????(4)display:fiex赞季;
? ? (5)position:absolute + margin愧捕;(有多種實現(xiàn)方式,可以具體查查)?
? ? (6)position:absolute(50%申钩, 50%) +?transform:translate(-50%,-50%)次绘; //實際原理和第5點很像
? ? (7)padding和margin + 已知距離;
? ? (更多.....?)
(五)實現(xiàn)接口同步請求的方式:
? ?當(dāng)時只回答出了函數(shù)內(nèi)回調(diào)(俗稱地獄回調(diào))撒遣、Promise邮偎、async(await)。 后來查了下愉舔,通過generator函數(shù)也可以钢猛。
(六)JS的數(shù)據(jù)類型和引用類型:
??六大數(shù)據(jù)類型:Number、String轩缤、Boolean命迈、Null贩绕、Object、undefind(我當(dāng)時漏掉這個)壶愤;
? 三大引用類型:Object淑倾、Array、Function征椒;
(七) 什么是高階函數(shù)
英文叫Higher-order function娇哆。JavaScript的函數(shù)其實都指向某個變量。既然變量可以指向函數(shù)勃救,函數(shù)的參數(shù)能接收變量碍讨,那么一個函數(shù)就可以接收另一個函數(shù)作為參數(shù),這種函數(shù)就稱之為高階函數(shù)蒙秒。常用高階函數(shù)有map/reduce/filter等等勃黍。
(八) Flex布局
Flex 是 Flexible Box 的縮寫,意為"彈性布局"晕讲,用來為盒狀模型提供最大的靈活性覆获。任何一個容器都可以指定為 Flex 布局∑笆。基本屬性:flex-basis弄息、flex-direction、flex-flow勤婚、flex-grow摹量、flex-shrink、flex-wrap
后話:
簡單粗略記錄了一下蛔六,希望以后再次面試到這個問題荆永,肚子有水還能再吹吹!(僅供參考国章,如有疑問錯誤請指出)