這篇文章主要總結(jié)在近期面試中遇到的答不上來或者答不完整的問題谈跛。題目都是自行查閱整理,不知道是不是面試官想要的答案塑陵。
1. JSBridge
JSBridge是連接Native(客戶端)和JavaScript前端的橋梁感憾,通過JSBridge 兩端的代碼才可以通信。
native訪問h5方法令花,只需在h5全局定義一個方法阻桅,native即可以調(diào)用。
h5調(diào)用native方法兼都,1)API注入嫂沉,native將方法掛在window上,h5使用window.xxx來調(diào)用扮碧;2)攔截url趟章,將url(自定義scheme:'ownHttp://xxx')放入iframe中插入頁面(display:none)杏糙,native攔截url執(zhí)行原生方法;3)h5的console,alert,prompt能夠被native攔截console.log('ownHttp://xxx')
2. redux 和 context 區(qū)別
redux是做狀態(tài)管理的蚓土,使用store存儲數(shù)據(jù)宏侍,action觸發(fā)事件,使用dispatch蜀漆,reducer處理時間谅河,用來修改狀態(tài)。
context提供了無需傳遞props就可以向組件傳遞數(shù)據(jù)的方法确丢。
兩者區(qū)別或者怎么選擇绷耍?
redux提供了對狀態(tài)的修改方法,而context只是單純的取值鲜侥。如果您正在處理一個更復雜的應用程序褂始,并希望查看您的應用程序的所有dispatch操作的歷史記錄,“點擊”其中任何一個并跳轉(zhuǎn)到該時間點描函,然后絕對考慮使用Redux崎苗。但是,如果你只想讓一些數(shù)據(jù)全局化以便從一堆組件中訪問它大可不必使用redux而用context赘阀。
3. react native 熱更新原理
暫時不好整理益缠,等我實際用到有所領(lǐng)悟再來補充把脑奠。
// TODO
4. 異常處理
- 使用 try-catch 語句
- onerror:任何沒有通過try-catch處理的錯誤都會觸發(fā)window對象的error事件基公。
將錯誤保存到服務器,標明是來自前端宋欺。利用img中的src路徑可以訪問跨域的地址轰豆,將錯誤傳到后端。
function logError(msg){
let img = new Image();
img.src = `http://xxx?msg=${encodeURIComponent(msg)}`
}
try{
}catch(err){
logError(err)
}
5. react hooks有什么缺點
- 目前暫時還沒有對應不常用的 getSnapshotBeforeUpdate齿诞,getDerivedStateFromError 和 componentDidCatch 生命周期的 Hook 等價寫法酸休。
- 目前 Hook 還處于早期階段,一些第三方的庫可能還暫時無法兼容 Hook祷杈。
額斑司,不知道面試官想到的是不是這個答案...
6. 虛擬dom除了渲染方面性能好,還有什么優(yōu)點
優(yōu)點:
- 保證性能下限: 框架的虛擬 DOM 需要適配任何上層 API 可能產(chǎn)生的操作但汞,它的一些 DOM 操作的實現(xiàn)必須是普適的宿刮,所以它的性能并不是最優(yōu)的;但是比起粗暴的 DOM 操作性能要好很多私蕾,因此框架的虛擬 DOM 至少可以保證在你不需要手動優(yōu)化的情況下僵缺,依然可以提供還不錯的性能,即保證性能的下限踩叭;
- 無需手動操作 DOM: 我們不再需要手動去操作 DOM磕潮,只需要寫好 View-Model 的代碼邏輯翠胰,框架會根據(jù)虛擬 DOM 和 數(shù)據(jù)雙向綁定,幫我們以可預期的方式更新視圖自脯,極大提高我們的開發(fā)效率之景;
- 跨平臺: 虛擬 DOM 本質(zhì)上是 JavaScript 對象,而 DOM 與平臺強相關(guān),相比之下虛擬 DOM 可以進行更方便地跨平臺操作冤今,例如服務器渲染闺兢、weex 開發(fā)等等。
缺點:
無法進行極致優(yōu)化: 雖然虛擬 DOM + 合理的優(yōu)化戏罢,足以應對絕大部分應用的性能需求屋谭,但在一些性能要求極高的應用中虛擬 DOM 無法進行針對性的極致優(yōu)化。
首次渲染大量DOM時龟糕,由于多了一層虛擬DOM的計算桐磁,會比innerHTML插入慢。
7. 強制緩存中cache-control設為no-cache后讲岁,就一定沒有緩存嗎我擂,協(xié)商緩存的緩存放在那里?
緩存是指代理服務器或客戶端本地磁盤內(nèi)保存的資源副本。利用緩存可減少對源服務器的訪問缓艳,因此也就節(jié)省了通信流量和通信時間校摩。
緩存服務器是代理服務器的一種,并歸類在緩存代理類型中阶淘。換句話說衙吩,當代理轉(zhuǎn)發(fā)從服務器返回的響應時,代理服務器將會保存一份資源的副本溪窒。
no-cache — 設了no-cache也可以在本地或者proxy服務器進行緩存坤塞,但是每次發(fā)起請求都要去服務器驗證,服務器返回可以使用緩存澈蚌,才可以真正使用本地緩存摹芙,任何節(jié)點都不能直接使用緩存。
協(xié)商緩存的緩存放在代理服務器宛瞄。
8. 解釋狀態(tài)碼 301 永久性定向和 302 臨時性定向
301: 永久性重定向浮禾。表示請求的資源已被更改為新的URI,以后應使用資源現(xiàn)在所指的 URI份汗。如果已經(jīng)把資源對應的 URI 保存為書簽了盈电,這時應該按 Location 首部字段提示的 URI 重新保存。
302:臨時性重定向裸影。該狀態(tài)碼表示請求的資源已被分配了新的 URI挣轨,希望用戶(本次)能使用新的 URI 訪問。已移動的資源對應的 URI 將來還有可能發(fā)生改變轩猩。
303:該狀態(tài)碼表示由于請求對應的資源存在著另一個 URI卷扮,應使用 GET 方法定向獲取請求的資源荡澎。303 狀態(tài)碼和 302 Found 狀態(tài)碼有著相同的功能,但 303 狀態(tài)碼明確 表示客戶端應當采用 GET 方法獲取資源晤锹,這點與 302 狀態(tài)碼有區(qū) 別摩幔。
304:該狀態(tài)碼表示客戶端發(fā)送附帶條件的請求(附帶條件的請求是指采用 GET方法的請求報文中包含 If-Match,If-Modified- Since鞭铆,If-None-Match或衡,If-Range,If-Unmodified-Since 中任一首部车遂。) 時封断,服務器端允許請求訪問資源,但未滿足條件的情況(有緩存舶担,沒有更新頁面)坡疼。
403 Forbidden:被拒絕了
500 Internal Server Error:該狀態(tài)碼表明服務器端在執(zhí)行請求時發(fā)生了錯誤。也有可能是 Web 應用存在的 bug 或某些臨時的故障衣陶。
503 Service Unavailable:該狀態(tài)碼表明服務器暫時處于超負載或正在進行停機維護柄瑰,現(xiàn)在無法 處理請求。
9. 0.1+0.1 != 0.3 js數(shù)值精度問題剪况,轉(zhuǎn)換成二進制計算導致精度丟失教沾,那么詳細講講精度是怎么丟失的
恕我無法描述出來,
請參考:
徹底弄懂:0.1+0.2 != 0.3
0.1+0.2 !== 0.3译断?
10. 手寫迭代器
function iterator(arr) {
let i = 0
return {
next: () => {
return {
value: i < arr.length ? arr[i++] : undefined,
done:i < arr.length ? false : true,
}
}
}
}
var it = iterator(['a', 'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next()
11. fib 斐波那契數(shù)列
題目:f(0) = 1, f(1) = 1, f(2) = 2, 實現(xiàn) f(n) = f(n-1)+ f(n-2)
這道題目是在面試官的引導下完成的授翻。首先寫一個最簡單的:
function f(n){
if(n<2) return 1
return f(n-1) + f(n-2)
}
然后面試官問我,這樣可以實現(xiàn)镐作,但是f(n) = f(n-1) + f(n-2), f(n-1) = f(n-2) + f(n-3)藏姐,在這樣遞歸計算的過程中隆箩,有每個值都被多次計算该贾,應該如何優(yōu)化,考慮將計算過的值存起來捌臊。 鄙人無能杨蛋,沒想到實現(xiàn)方法,理澎,逞力,面試官提醒我可以利用Map,
var obj = new Map()
function f(n) {
if (n < 2) return 1
if (obj.has(n)) return obj.get(n)
const value = f(n - 1) + f(n - 2)
obj.set(n, value)
return value
}
或者使用for循環(huán)來計算
var arr = [1, 1]
function f(n) {
if(arr[n]) return arr[n]
for (let i = 2; i <= n; i++) {
arr[i] = arr[i - 1] + arr[i - 2]
}
return arr[n]
}
12. typeof null == 'object'原因
“typeof null 為"object", 原因是因為 不同的對象在底層都表示為二進制,在Javascript中二進制前三位都為0的話會被判斷為Object類型,null的二進制表示全為0,自然前三位也是0,所以執(zhí)行typeof時會返回"object"糠爬。
這個bug是第一版Javascript留下來的寇荧。在這個版本,數(shù)值是以32字節(jié)存儲的执隧,由標志位(1~3個字節(jié))和數(shù)值組成揩抡。標志位存儲的是低位的數(shù)據(jù)户侥。這里有五種標志位:
000:對象,數(shù)據(jù)是對象的應用峦嗤。
1:整型蕊唐,數(shù)據(jù)是31位帶符號整數(shù)。
010:雙精度類型烁设,數(shù)據(jù)是雙精度數(shù)字替梨。
100:字符串,數(shù)據(jù)是字符串装黑。
110:布爾類型副瀑,數(shù)據(jù)是布爾值。
參考: https://blog.csdn.net/weixin_42952665/article/details/82750684
13. 實現(xiàn)深拷貝
我給出的答案:
var deepCopy = (function f(target) {
if (typeof target !== 'object') return
var newData = target instanceof Array ? [] : {};
for (var item in target) {
if (target.hasOwnProperty(item)) {
newData[item] = typeof target[item] == 'object' ? f(target[item]) : target[item];
}
}
return newData;
})
面試官靈魂拷問1: 第一句if (typeof target !== 'object') return
基礎類型傳進來就return了嗎恋谭,什么也不返回俗扇? 我說那就把target再返回去。
2:typeof target !== 'object' 判斷對象一定準確嗎箕别?碰到null怎么辦铜幽?我心里默想那就再加一個判斷它不是null,追問:碰到Date怎么辦串稀? 額除抛,我心里想那要判斷的有點多了,確實不合適母截。面試官指導:
對象類型的轉(zhuǎn)換為字符串會變成 "[object Object]",null會變?yōu)?[object Null]"到忽,數(shù)組會變?yōu)?[object Array]",能否利用?
Object.prototype.toString.call(target)
3:newData[item] = typeof target[item] == 'object' ? f(target[item]) : target[item];
這句不可以直接用newDate[item] = f(target[item])
嗎清寇?我說基礎類型走遞歸不太好吧喘漏,他說,如果第一句就return了target华烟,那不也沒執(zhí)行下邊的嗎翩迈?
嚯,
經(jīng)過我最終整理盔夜,實現(xiàn)如下:
var deepCopy = (function f(target) {
// 將目標轉(zhuǎn)換為字符串來判斷類型负饲,null轉(zhuǎn)換為"[object Null]",
// new Date():"[object Date]",數(shù)值:"[object Number]"喂链,字符串:"[object String]"等
const type = Object.prototype.toString.call(target);
let newData = type == '[object Object]' ? {} : (type == '[object Array]' ? [] : false)
if(!newData) return target
for (var item in target) {
//只復制元素自身的屬性返十,不復制原型鏈上的
if (target.hasOwnProperty(item)) {
newData[item] = f(target[item]);
}
}
return newData;
})
這次應該沒問題了把。椭微。洞坑。
14. 列舉會使GPU硬件加速的css屬性
先來了解一下何為GPU硬件加速:
就是將瀏覽器的渲染過程交給GPU處理,而不是使用自帶的比較慢的渲染器蝇率。這樣就可以使得animation與transition更加順暢迟杂。一般一個元素開啟硬件加速后會變成合成層匈仗,可以獨立于普通文檔流中,改動后可以避免整個頁面重繪逢慌,提升性能悠轩,因此我們可以在瀏覽器中用css開啟硬件加速,使GPU (Graphics Processing Unit) 發(fā)揮功能攻泼。
可以觸發(fā)硬件加速的css屬性:
transform
opacity
filter
為什么硬件加速會使頁面流暢火架?
因為 transform 屬性不會觸發(fā)瀏覽器的 repaint(重繪),而絕對定位absolute中的 left 和 top 則會一直觸發(fā) repaint(重繪)忙菠。
為什么 transform 沒有觸發(fā) repaint 呢何鸡?簡而言之,transform 動畫由GPU控制牛欢,支持硬件加速骡男,并不需要軟件方面的渲染。
如何開啟硬件加速傍睹?
CSS animations, transforms 以及 transitions 不會自動開啟GPU加速隔盛,3d動畫才會開啟:translateZ( ) 或 translate3d( ),但是很多時候并不需要3d變換:
webkit-transform : translateZ ( 0 ) ;
-moz-transform : translateZ ( 0 ) ;
-ms-transform : translateZ ( 0 ) ;
-o-transform : translateZ ( 0 ) ;
transform : translateZ ( 0 ) ;
webkit-transform : translate3d ( 0 , 0 , 0 ) ;
-moz-transform : translate3d ( 0 , 0 , 0 ) ;
-ms-transform : translate3d ( 0 , 0 , 0 ) ;
-o-transform : translate3d ( 0 , 0 , 0 ) ;
transform : translate3d ( 0 , 0 , 0 ) ;
在 Chrome and Safari中拾稳,當我們使用CSS transforms 或者 animations時可能會有頁面閃爍的效果吮炕,下面的代碼可以修復此情況:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
15. 列舉pc端和移動端的兼容性問題和解決方案
移動端:
- 不同瀏覽器的最小字體不同,有的是10px访得,有的是12px
解決辦法:設置字體時龙亲,不要小于12px,如果一定要小于12px,使用transform:sacle()進行縮放 - 透明度opacity
解決辦法:IE8 以及更早的版本支持替代的 filter 屬性悍抑。例如:filter:Alpha(opacity=50) - Input 的placeholder會出現(xiàn)文本位置偏上的情況
input 的placeholder會出現(xiàn)文本位置偏上的情況:PC端設置line-height等于height能夠?qū)R鳄炉,而移動端仍然是偏上,解決是設置line-height:normal
PC端:
- 如果圖片加a標簽在IE9-中會有邊框
解決方案:img{border:none;} - display:inline-block ie6/7不支持
解決方案: display:inline; - 標準的事件綁定方法函數(shù)為addEventListener搜骡,但IE下是attachEvent拂盯;
16. SEO(搜索引擎優(yōu)化)
SEO的存在就是為了提升網(wǎng)頁在搜索引擎自然搜索結(jié)果中的收錄數(shù)量以及排序位置而做的優(yōu)化行為。而優(yōu)化的目的就是為了提升網(wǎng)站在搜索引擎中的權(quán)重浆兰,增加對搜索引擎的友好度磕仅,使得用戶在訪問網(wǎng)站時能排在前面珊豹。
如何做簸呈?
- 網(wǎng)站結(jié)構(gòu)布局優(yōu)化:盡量簡單、開門見山店茶,提倡扁平化結(jié)構(gòu)
(1) 控制首頁鏈接數(shù)量
(2) 扁平化的目錄層次
(3) 導航優(yōu)化:導航應該盡量采用文字方式蜕便,也可以搭配圖片導航,<img>標簽必須添加“alt”和“title”屬性贩幻,告訴搜索引擎導航的定位轿腺。在每一個網(wǎng)頁上應該加上面包屑導航两嘴。
(4)網(wǎng)站的結(jié)構(gòu)布局---不可忽略的細節(jié)
(5)利用布局,把重要內(nèi)容HTML代碼放在最前
(6)控制頁面的大小族壳,減少http請求憔辫,提高網(wǎng)站的加載速度 - 網(wǎng)頁代碼優(yōu)化
(1)突出重要內(nèi)容---合理的設計<title>、<meta description>和<meta keywords>
(2)語義化書寫HTML代碼仿荆,符合W3C標準.eg:標題用h1-h6,列表用ul,li,重要文字用strong
(3)<a>標簽:頁內(nèi)鏈接贰您,要加 “title” 屬性加以說明,讓訪客和 “蜘蛛” 知道拢操。而外部鏈接锦亦,鏈接到其他網(wǎng)站的,則需要加上 el="nofollow" 屬性, 告訴 “蜘蛛” 不要爬令境,因為一旦“蜘蛛”爬了外部鏈接之后杠园,就不會再回來了。
等舔庶。抛蚁。。 - 前端網(wǎng)站性能優(yōu)化
(1)減少http請求數(shù)量.CSS Sprites(圖片精靈)惕橙,合并CSS和JS文件(使用grunt篮绿、gulp、webpack等)吕漂,采用lazyload(懶加載)
(2)控制資源文件加載優(yōu)先級
(3)盡量外鏈CSS和JS(結(jié)構(gòu)亲配、表現(xiàn)和行為的分離),保證網(wǎng)頁代碼的整潔惶凝,也有利于日后維護
(4)利用瀏覽器緩存
(5)減少重排(Reflow)
(6)減少 DOM 操作
(7)圖標使用IconFont替換
等吼虎。。苍鲜。
參考:https://juejin.cn/post/6844903824428105735
17. SSR
是什么思灰?
server side render,服務端渲染混滔。即:SSR大致的意思就是客戶端將標簽渲染成的整個 html 片段的工作在服務端完成洒疚,服務端形成的html 片段直接返回給客戶端這個過程就叫做服務端渲染。
優(yōu)缺點坯屿?
優(yōu)點:
- 更好的 SEO油湖。 因為 SPA (單頁面應用)頁面的內(nèi)容是通過 Ajax 獲取,而搜索引擎爬取工具并不會等待 Ajax 異步完成后再抓取頁面內(nèi)容领跛,所以在 SPA 中是抓取不到頁面通過 Ajax 獲取到的內(nèi)容乏德;而 SSR 是直接由服務端返回已經(jīng)渲染好的頁面(數(shù)據(jù)已經(jīng)包含在頁面中),所以搜索引擎爬取工具可以抓取渲染好的頁面。
- 更快的內(nèi)容到達時間(首屏加載更快): SPA 會等待所有編譯后的 js 文件都下載完成后喊括,才開始進行頁面的渲染胧瓜,文件下載等需要一定的時間等,所以首屏渲染需要一定的時間郑什;SSR 直接由服務端渲染好頁面直接返回顯示府喳,無需等待下載 js 文件及再去渲染等,所以 SSR 有更快的內(nèi)容到達時間蘑拯。
缺點:
- 更多的開發(fā)條件限制: 例如服務端渲染在vue中只支持beforCreate和 created 兩個鉤子函數(shù)劫拢,這會導致一些外部擴展庫需要特殊處理,才能在服務端渲染應用程序中運行强胰;并且與可以部署在任何靜態(tài)文件服務器上的完全靜態(tài)單頁面應用程序SPA不同舱沧,服務端渲染應用程序,需要處于 Node.js server 運行環(huán)境偶洋;
- 更多的服務器負載:在 Node.js 中渲染完整的應用程序熟吏,顯然會比僅僅提供靜態(tài)文件的 server 更加大量占用CPU 資源 (CPU-intensive - CPU 密集),因此如果你預料在高流量環(huán)境 ( high traffic ) 下使用玄窝,請準備相應的服務器負載牵寺,并明智地采用緩存策略。
參考: https://juejin.cn/post/6913752813403111438
18. PWA
PWA全稱Progressive Web App恩脂,即漸進式WEB應用帽氓。
一個 PWA 應用首先是一個網(wǎng)頁, 可以通過 Web 技術(shù)編寫出一個網(wǎng)頁應用. 隨后添加上 App Manifest 和 Service Worker 來實現(xiàn) PWA 的安裝和離線等功能
解決了哪些問題?
- 可以添加至主屏幕俩块,點擊主屏幕圖標可以實現(xiàn)啟動動畫以及隱藏地址欄
- 實現(xiàn)離線緩存功能黎休,即使用戶手機沒有網(wǎng)絡,依然可以使用一些離線功能
- 實現(xiàn)了消息推送
它解決了上述提到的問題玉凯,這些特性將使得 Web 應用漸進式接近原生 App势腮。
參考:
講講PWA
Service Worker