寫在前面:大前端日益更新、對開發者的要求也越來越高。下面我先列出我能想到的面試題大綱,然后一一解答,給自己做個筆記。
一、基礎
1). css部分
- 移動端常用適配方式
px+%
rem
vw
- css 垂直水平居中
已知寬高:
background: red;
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
不知寬高 用定位+transform
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
flex 布局:
display: flex;
align-items: center;
justify-content: center;
等等..
- rem、em 原理區別
rem 根據根元素的字體大小進行適配
em 根據父元素的字體大小進行適配
- 盒模型
w3c標准合模型 width:content
IE盒模型 width: content + padding + border
- 清除浮動的幾種方式
給父元素設置高度
偽類
- css畫出一個三角形
寬高都設為0 用border 實現效果
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
- 內聯、import 、support 權重優先級
import>內聯>Support
- BFC
- Block Formatting Contexts (塊級格式化上下文) 。具有 BFC 特性的元素可以看作是隔離了的獨立容器,容器里面的元素不會在布局上影響到外面的元素,並且 BFC 具有普通容器所沒有的一些特性。
-
只要元素滿足下面任一條件即可觸發 BFC 特性:
body 根元素
浮動元素:float 除 none 以外的值
絕對定位元素:position (absolute、fixed)
overflow 除了 visible 以外的值 (hidden、auto、scroll)的值為 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個
3. 同一個 BFC 下外邊距會發生折疊
4.BFC 可以包含浮動的元素(清除浮動)
2). html 部分
- h5 新標簽
header,footer,main,nav,section 等等.
- 瀏覽器內核
- IE瀏覽器內核:Trident內核,也是俗稱的IE內核;
- Chrome瀏覽器內核:統稱為Chromium內核或Chrome內核,以前是Webkit內核,現在是Blink內核;
- Firefox瀏覽器內核:Gecko內核,俗稱Firefox內核;
- Safari瀏覽器內核:Webkit內核;
- Opera瀏覽器內核:最初是自己的Presto內核,后來是Webkit,現在是Blink內核;
- 360瀏覽器、獵豹瀏覽器內核:IE+Chrome雙內核;
- 搜狗、遨游、QQ瀏覽器內核:Trident(兼容模式)+Webkit(高速模式);
- 百度瀏覽器、世界之窗內核:IE內核;
- 2345瀏覽器內核:以前是IE內核,現在也是IE+Chrome雙內核;
- 瀏覽器兼容
- css里增加通配符*{margin:0;padding:0}
- 使用float為img布局 解決圖片默認間距. 等等
由於瀏覽器兼容問題比較開放性 面試的時候 可以跟面試官扯一些你在項目中遇到的兼容方式.如果沒有經驗 可專門百度.
此處放一個參考鏈接 https://www.jianshu.com/p/6afd596440bb
- dom 渲染
瀏覽器解析html源碼,然后創建一個DOM樹。
瀏覽器解析CSS代碼,計算出最終的樣式數據。
創建完DOM樹並得到最終的樣式數據之后,構建一個渲染樹。
當渲染樹創建完成之后,瀏覽器就可以根據渲染樹直接把頁面繪制到屏幕上。
這個可以根據自己的理解解答 不用死記硬背.
3). js
- get和post 區別和相同點。以及還有哪些別的請求方式?
相同點:
都是http 請求方式。都屬於TCP連接。
區別:
get 在瀏覽器是回退時是無害的,而post會再次提交請求。
get 請求會被瀏覽器主動cache(緩存),而post不會除非手動設置。
get請求只能進行url 編碼,post支持多種編碼方式。
get請求參數會被完整保留在瀏覽器歷史記錄里,post 不會保留
get 請求在url 傳送參數有長度限制 ,post 沒有
get 請求通過url 傳參, post 參數放在request body 中
get 請求因為參數放在url 上的原因 相比較post而言 不安全
get 請求產生有一個TCP數據包 ,post 會產生兩個TCP數據包
具體原理 參考鏈接傳送門
- 數據類型
ES5六種:
Number、String、Boolean、undefined、object、Null。
其中object為引用類型(Data、function、Array等)。
其余五種為基本類型。
ES6 中新增了一種 Symbol 。
- JavaScript中的作用域與變量聲明提升
所有的變量聲明都會被提升到作用域的最頂端
同一個變量聲明只進行一次 其他聲明會被重置掉
函數聲明的優先級高於變量聲明 且函數聲明會連帶定義一起提升
這個面試題一般會直接以題的形式考察你的掌握度,看先打印出哪一個值。具體還需自己多理解掌握。
- 數組的方法(不止增刪改查)

控制台打印輸出一個數組里 _proto_ 里包含的都是數組可以點出來的操作方法。多說幾個不常用的會更加分。
- 瀏覽器渲染
自上而下加載。遇見css和圖片異步加載。js代碼會先解析js加載完之后再繼續渲染(這也是為什么script標簽往往會放在body后面的原因)。
1.當用戶輸入一個url 之后,瀏覽器會去向服務器發起請求請求url 對應的資源;
2.接收到服務器響應內容之后,瀏覽器的html 解析器會將HTML文件解析成一個DOM樹。 將CSS解析成一個CSS 樹;
3.根據DOM樹和CSS樹來構建 Render Tree(渲染樹)。根據渲染樹的對應關系 在客戶端呈現內容畫面。
- 面向對象、閉包、原型、原型鏈
1. 面向對象的基本特征:封裝、繼承、多態。把客觀的事物封裝成抽象的類,或者構造函數。
2. 閉包:能夠訪問另一個函數作用域變量的函數。顧名思義:函數中的函數。缺點:內存泄漏,this指向問題,引用的變量可能會發生變化。
優點:可以解決遞歸調用,模仿塊級作用域。
3. 原型:每個構造函數都有prototype 屬性指向另一個對象。這個對象的所有屬性和方法都會被構造函數的實例繼承。
我們可以把不變的屬性和方法定義在prototype對象上。prototype默認有兩個屬性,constructor屬性和__proto__屬性,
_proto_是原型鏈指向實例化的函數原型,總是指向prototype。hasOwnProperty()來查看是否是自身屬性 還是繼承屬性。
- 事件機制、(冒泡,捕獲)
冒泡:事件冒泡是 IE 團隊提出的事件流方案,根據名字我們就可以看出,事件冒泡是從最具體的元素開始觸發事件,然后向上傳播至沒有那么具體的元素(文檔)。簡而言之:由內而外的觸發機制。
捕獲:事件捕獲是 Netscpe 開發團隊提出的事件流解決方案。和事件冒泡相反,事件捕獲是從最不具體的節點最先接收事件,向下傳播至最具體的節點。事件捕獲實際上是為了在事件到達最終目標前攔截事件。簡而言之:由外而內的觸發機制。
preventDefault() 方法用於阻止特點事件的默認行為(比如,a 標簽有跳轉到 href 鏈接的默認行為,可以阻止這種導航行為)。
stopPropagation() 方法用於立即阻止事件流在 DOM 結構中的傳播,取消后續的事件捕獲或冒泡。
- 跨域及解決方式
為什么會跨域?出於瀏覽器的同源策略限制,瀏覽器會拒絕跨域請求。
什么叫跨域?非同源請求,均為跨域。名詞解釋:同源 —— 如果兩個頁面擁有相同的協議(protocol),端口(port)和主機(host),那么這兩個頁面就屬於同一個源(origin)。
怎么解決跨域?最常用的三種方式:JSONP、CORS、postMessage。
【JSONP的優缺點】
優點:兼容性好(兼容低版本IE)
缺點:1.JSONP只支持GET請求; 2.XMLHttpRequest相對於JSONP有着更好的錯誤處理機制
CORS :是W3C 推薦的一種新的官方方案,能使服務器支持 XMLHttpRequest 的跨域請求。CORS 實現起來非常方便,只需要增加一些 HTTP 頭,讓服務器能聲明允許的訪問來源。
- Ajax 原理
簡言之:異步請求數據。原理結合原生ajax 請求步驟 (即下面代碼的大致步驟)更加分。
實現流程:
- 創建一個
XMLHttpRequest對象 - 創建一個新的
HTTP請求,並指定該請求的方法、URL以及是否為異步請求 - 設置響應
HTTP請求狀態變化的函數 - 發送
HTTP請求 - 對異步返回的數據進行處理
// 創建 XMLHttpRequest 對象 var xhr if (window.XMLHttpRequest) { xhr = new XMLHttpRequest() } else if (window.ActiveXObject) { xhr = new ActiveXObject('Microsoft.XMLHTTP') } // 創建一個新的請求 xhr.open('GET', 'http://www.example.com', true) // 設置請求頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 監聽 HTTP 請求狀態變化 xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var res = xhr.responseText } } // 發送 HTTP 請求 xhr.send()
優點:
頁面無刷新,用戶體驗好
使用異步的方式與服務器通信,響應更加迅速
減輕服務器的壓力,節約帶寬
基於標准化並被廣泛支持的技術
缺點:
破壞了瀏覽器的回退機制
暴露了更多的數據和服務器邏輯
對搜索引擎的支持比較弱
違背了 URL 與資源定位的初衷
- 緩存(session、cookie、localstorage)特點,區別
cookie 特點:
1.不同的瀏覽器存放的cookie位置不一樣,也是不能通用的。
2.cookie的存儲是以域名形式進行區分的,不同的域下存儲的cookie是獨立的。
3.我們可以設置cookie生效的域(當前設置cookie所在域的子域),也就是說,我們能夠操作的cookie是當前域以及當前域下的所有子域
4.一個域名下存放的cookie的個數是有限制的,不同的瀏覽器存放的個數不一樣,一般為20個。
5.每個cookie存放的內容大小也是有限制的,不同的瀏覽器存放大小不一樣,一般為4KB。
6.cookie也可以設置過期的時間,默認是會話結束的時候,當時間到期自動銷毀
localStorage(本地存儲):
1.生命周期:持久化的本地存儲,除非主動刪除數據,否則數據是永遠不會過期的。
2.存儲的信息在同一域中是共享的。
3.當本頁操作(新增、修改、刪除)了localStorage的時候,本頁面不會觸發storage事件,但是別的頁面會觸發storage事件。
4.大小:據說是5M(跟瀏覽器廠商有關系)
5.在非IE下的瀏覽中可以本地打開。IE瀏覽器要在服務器中打開。
6.localStorage本質上是對字符串的讀取,如果存儲內容多的話會消耗內存空間,會導致頁面變卡
7.localStorage受同源策略的限制
sessionStorage(本地會話存儲):
用於本地存儲一個會話(session)中的數據,這些數據只有在同一個會話中的頁面才能訪問並且當會話結束后數據也隨之銷毀。因此sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。也就是說只要這個瀏覽器窗口沒有關閉,即使刷新頁面或進入同源另一頁面,數據仍然存在。關閉窗口后,sessionStorage即被銷毀,或者在新窗口打開同源的另一個頁面,sessionStorage也是沒有的。
cookie、localStorage、sessionStorage區別
相同:在本地(瀏覽器端)存儲數據
不同:
localStorage、sessionStorage
localStorage只要在相同的協議、相同的主機名、相同的端口下,就能讀取/修改到同一份localStorage數據。
sessionStorage比localStorage更嚴苛一點,除了協議、主機名、端口外,還要求在同一窗口(也就是瀏覽器的標簽頁)下。
localStorage是永久存儲,除非手動刪除。
sessionStorage當會話結束(當前頁面關閉的時候,自動銷毀)
cookie的數據會在每一次發送http請求的時候,同時發送給服務器而localStorage、sessionStorage不會。
- jQuery 選擇器
id選擇器: $( "#id" )
類名選擇器: $( ".class" )
標簽選擇器: $( "div" )
以上三種是最常用。稍微復雜點的參考鏈接
- HTTP 狀態碼及含義
200 OK ,表明請求已經成功. 默認情況下狀態碼為200的響應可以被緩存。
302 Found,臨時重定向。重定向狀態碼表明請求的資源被暫時的移動到了由 Location 頭部指定的 URL 上。瀏覽器會重定向到這個URL,但是搜索引擎不會對該資源的鏈接進行更新。
400 Bad Request,表示由於語法無效,服務器無法理解該請求。客戶端不應該在未經修改的情況下重復此請求。
403 Forbidden,指的是服務器端有能力處理該請求,但是拒絕授權訪問。進入該狀態后,不能再繼續進行驗證。該訪問是永久禁止的,並且與應用邏輯密切相關(例如不正確的密碼)
404 Not Found,說明服務器端無法找到所請求的資源。404 不能說明請求的資源是臨時還是永久丟失。如果服務器知道該資源是永久丟失,那么應該返回 410 (Gone) 而不是 404 。
500 Internal Server Error,表示所請求的服務器遇到意外的情況並阻止其執行請求。
502 Bad Gateway,表示作為網關或代理角色的服務器,從上游服務器(如tomcat、php-fpm)中接收到的響應是無效的。服務器掛掉了的意思。
503 Serveice Unavailable,表示服務器尚未處於可以接受請求的狀態。
更詳細解析參考鏈接
- 異步加載和延遲加載
異步async:
async HTML5里為script標簽里新增了async屬性,用於異步加載腳本: 不保證順序(獨立的個體)
<script async src="script.js"></script> /*或*/ <script type="text/javascript" src="alert.js" async="async"></script>
瀏覽器解析到HTML里的該行script標簽,發現指定為async,會異步下載解析執行腳本(即加載后續文檔元素的過程將和script.js的加載並行進行)。
頁面的DOM結構里假設<script>在img之前,如果你的瀏覽器支持async的話,就會異步加載腳本。此時DOM里已經有img了,所以腳本里能順利取到img的src並彈框。
延遲defer:
defer <script>標簽里可以設置defer,表示延遲加載腳本:腳本先不執行,延遲到文檔解析和顯示后執行,有順序。
<script defer src="script.js"></script> /*或*/ <script type="text/javascript" src="alert.js" defer="defer"></script>
瀏覽器解析到HTML里該行<script>標簽,發現指定為defer,會暫緩下載解析執行腳本,等到頁面文檔解析並加載執行完畢后,才會加載該腳本(更精確地說,是在DOM樹構建完成后,在DOMContentLoaded事件觸發前,加載defer的腳本)。
頁面的DOM結構里假設script在img圖片之前,如果你的瀏覽器支持defer的話,就會延遲到頁面加載完后才下載腳本。此時DOM里已經有img元素了,所以腳本里能順利取到img的src並彈框。
詳情參考鏈接
4). 優化
- 前端性能優化的方法
- 優雅降級和漸進增強
- 節流和防抖
二、進階
1).vue
- 組件之間傳值方式有哪些?
- 父組件向子組件傳遞數據 通過props
- 子組件像父組件傳遞事件$emit方法
- eventbus
- vuex
- 緩存機制
- 父子組件 互相調用 方法的方式有哪些?
父組件調用子組件的方法:this.$refs.子組件ref值.子組件event
子組件調用父組件方法:
this.$parent.event
this.$emit.event(與傳值方式相同)
父組件把事件傳到子組件props 中 子組件調用
- vue生命周期的理解 created和 mounted 之間的區別
創建:初始化事件、進行數據觀測
beforeCreate
created(數據已經和data 綁定,改變data里的屬性值、視圖會發生變化。由於視圖未出現,如果請求信息過多,頁面會處於長時間白屏)
掛載:判斷對象是否有el選項,如果有繼續編譯,如果沒有 生命周期停止。直到vue實例調用vm.$mount(el).
beforeMount (模板編譯完成 但未掛載 獲取不了DOM)
mounted(組件掛載完成,能成功獲取DOM,所有的子組件不一定會被掛載,可以等到整個視圖都渲染完畢后 用vm.$nextTick)
更新:vue發現data 數據更新 會重新渲染
beforeUpdate
updated
銷毀:常用於組件變更時的狀態存儲 和 內存釋放
beforeDistory
distoryed(不會自動移除dom 節點,可以手動在生命周期里操作)
- vue組件中為什么data 是一個函數 而不是一個對象
因為JavaScript的特性所導致,在component中,data必須以函數的形式存在,不可以是對象。
組建中的data寫成一個函數,數據以函數返回值的形式定義,這樣每次復用組件的時候,都會返回一份新的data,相當於每個組件實例都有自己私有的數據空間,它們只負責各自維護的數據,不會造成混亂。而單純的寫成對象形式,就是所有的組件實例共用了一個data,這樣改一個全都改了。
- vue computed 和 watch 的區別 使用場景
computed:
- 有緩存機制、依賴項發生改變重新計算。
- 不支持異步,當computed 內部有異步操作時、無法監聽數據變化
- 不需要在data里聲明
- 一個屬性受多個屬性影響時使用
- 使用 場景:購物車結算
watch:
- 沒有緩存機制,數據發生變化直接觸發
- 支持異步操作
- 必須在data里聲明
- 數據變化時執行異步或開銷較大的操作(一條數據影響多條數據的時候)
- 使用場景:搜索、滾動錨點定位
- vuex action 和 mutation之間的區別
mutation 定義的方法動態修改Vuex 的 store 中的狀態或數據。view 層通過 store.commit來分發,必須同步執行。
action可以理解為通過將mutations里面處里數據的方法變成可異步的處理數據的方法,簡單的說就是異步操作數據。view 層通過 store.dispath 來分發 action,不能直接操作state。
- v-show和v-if指令的共同點和不同點
都是隱藏不可見元素
v-show 不管條件是否為真 都會渲染 控制元素的display 屬性 來控制顯示隱藏 有更高的初始渲染開銷
v-if 是根據條件來判斷是否渲染 頻繁的重建和銷毀節點 會有更高的切換開銷
- vue優點和缺點
優點:輕量級
數據驅動視圖 組件化
高效、快速、模塊友好
缺點:不利於seo
不支持低版本瀏覽器
第一次加載首頁耗時過長
不能使用瀏覽器的導航 需要自行實現路由前進后退
- 說出幾種vue當中的指令和它的用法
v-model 雙向數據綁定
v-for 循環遍歷 比v-if 優先級高
v-show、v-if 隱藏
v-once 只綁定一次
- vue-loader是什么?使用它的用途有哪些?
vue 文件加載器, 將style/template/js 轉換成js模塊。js可以寫es6、style樣式可以scss或less、template可以加jade等
- 為什么使用key?
需要使用key來給每個節點做一個唯一標識,Diff算法就可以正確的識別此節點。
作用主要是為了高效的更新虛擬DOM。
- $nextTick的使用
當你修改了data的值然后馬上獲取這個dom元素的值,是不能獲取到更新后的值,
你需要使用$nextTick這個回調,讓修改后的data值渲染更新到dom元素之后在獲取,才能成功
- vue 雙向數據綁定原理?
采用數據劫持和發布者-訂閱者模式的方式,通過object.defineProperty劫持各個屬性的getter、setter 方法,在數據變動時發布消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉為 getter/setter。用戶看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。vue的數據雙向綁定 將MVVM作為數據綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監聽自己的model的數據變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通信橋梁,達到數據變化 —>視圖更新;視圖交互變化(input)—>數據model變更雙向綁定效果。
- vue路由實現,hash模式 和 history模式區別
hash: hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對后端完全沒有影響,因此改變 hash 不會重新加載頁面。僅hash符號之前的內容會被包含在請求中,因此對后端來說,即使沒有做到對路由的全覆蓋,也不會返回404錯誤
history: 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支持)這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向后端發送請求。前端發出的url請求必須和實際像后端發出的請求一致,否則會返回404錯誤
- keepalive
是 Vue 內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。在vue 2.1.0 版本之后,keep-alive新加入了兩個屬性: include(包含的組件緩存) 與 exclude(排除的組件不緩存,優先級大於include) 。
- $router 和 $route 區別
$router是VueRouter的實例對象,有push、replace等方法;
$route是路由信息對象、獲取頁面傳遞的參數,path、params、hash、query等路由信息參數;
- vue常用修飾符
.prevent 阻止事件默認行為 =event.preventDefault()
.stop 阻止事件冒泡 = event.stopPropagation()
.self 事件僅作用於元素本身,子組件不會觸發
.capture 事件偵聽,事件捕獲
- params和query的區別
query要用path來引入,params要用name來引入,接收參數都是類似的,分別是this.$route.query.name和this.$route.params.name。
url地址顯示:query更加類似於我們ajax中get傳參,params則類似於post,說的再簡單一點,前者在瀏覽器地址欄中顯示參數,后者則不顯示
注意點:query刷新不會丟失query里面的數據,params刷新 會 丟失 params里面的數據。
