前端面試題整理(部分)

HTML
一、BFC 塊級(jí)格式化上下文:里面的元素不會(huì)影響外面的元素。
  • 一個(gè)BFC區(qū)域只包含其子元素,不包括子元素的子元素
  • BFC區(qū)域需要一定的條件:該元素設(shè)置浮動(dòng)、定位、彈性布局等
  • 不同的BFC區(qū)域之間是相互獨(dú)立的
二、移動(dòng)端點(diǎn)擊300ms延遲
  • fastclick插件:是在檢測(cè)到touchend事件的時(shí)候,會(huì)通過(guò)DOM自定義事件立即出發(fā)模擬一個(gè)click事件,并把瀏覽器在300ms之后的click事件阻止掉。ios會(huì)首次觸發(fā)不生效、需要二次觸發(fā)
  • touchStart配合touchend,記錄的值進(jìn)行對(duì)比判斷
三、meta viewport 為了防止用戶(hù)縮放前端頁(yè)面-適配移動(dòng)端頁(yè)面、 meta元數(shù)據(jù)
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />
四、@import 和link引入 css
  • @import先加載HTML、后加載CSS
  • link先加載CSS、后加載HTML rel="stylesheet" 連接的類(lèi)型 樣式表
五、src和href的區(qū)別
  • href指定網(wǎng)絡(luò)資源的位置,建立和當(dāng)前元素之間的連接
  • src僅僅嵌入當(dāng)前資源到當(dāng)前文檔元素定義的位置
六、偽類(lèi)和偽元素的區(qū)別
  • 是否創(chuàng)建新元素;偽類(lèi) 添加特殊效果,單冒號(hào);偽元素 雙冒號(hào)
  • 偽類(lèi)選擇器: a:link\a:visited\a:hover\a:active等
七、圣杯和雙飛翼布局:三欄布局;左右固定寬度,中間寬度自適應(yīng)
  • 利用margin的負(fù)值、配合float進(jìn)行布局;(中間盒子的左右margin或者父盒子左右padding)
  • flex:父盒子設(shè)置flex,兩側(cè)設(shè)置 flex:0;flex-basic: 固定寬度。
八、漸進(jìn)增強(qiáng)、優(yōu)雅降級(jí)
  • 漸進(jìn)增強(qiáng):針對(duì)低版本瀏覽器進(jìn)行構(gòu)建頁(yè)面,保證最基本的 功能。
  • 優(yōu)雅降級(jí):一開(kāi)始就開(kāi)始構(gòu)建完整的功能,然后針對(duì)低版本瀏覽器進(jìn)行兼容。
七、常見(jiàn)瀏覽器兼容性:
  • 瀏覽器種類(lèi)多,內(nèi)核種類(lèi)多,對(duì)于CSS3的部分屬性不能完全兼容。 條件注釋、選擇器前綴法

八、重排(回流)、重繪

  • 重排:當(dāng)元素的位置和尺寸大小,瀏覽器需要重新計(jì)算元素的幾何屬性,像添加和刪除DOM、元素尺寸改變。
  • 重繪:一個(gè)元素的外觀發(fā)生變化,但是沒(méi)有改變布局,重新把元素外觀繪制出來(lái)的過(guò)程。
  • transform:不重排、不重繪。合成屬性,會(huì)創(chuàng)建一個(gè)合成層,在合成層上渲染。
九、檢測(cè)是否為數(shù)組; 原型鏈
  • Object.prototype.toString.call() [object Array]
  • Array.isArray() 、instanceof:判斷該對(duì)象是誰(shuí)的實(shí)例 、 typeof

十、typeof和instanceof

  • typeof是一個(gè)操作符,用來(lái)檢測(cè)給定變量的數(shù)據(jù)類(lèi)型;原理數(shù)據(jù)底層機(jī)制,二進(jìn)制判斷
  • instanceof是通過(guò)JavaScript原型繼承機(jī)制
十一、閉包 -
  • 有權(quán)訪(fǎng)問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù)
  • 應(yīng)用場(chǎng)景:函數(shù)防抖(在事件被觸發(fā)N秒后再執(zhí)行回調(diào),如果在這時(shí)間內(nèi)又被觸發(fā),則重新計(jì)時(shí))
function debounce(fn, delay) {
  let timer = null
  return function () {
    if (timer) {
      clearTimeOut(timer)
      timer = setTimeOut(fn, delay)
    } else {
      timer = setTimeOut(fn, delay)
    }
  }
} // 短時(shí)間內(nèi)大量觸發(fā)同一事件,只會(huì)執(zhí)行一次函數(shù) 且肯定會(huì)執(zhí)行
function throttle(fn, delay) {
    let flag = true
  return function() {
    if (!flag) {
      flag = false
    }
    flag = false
    setTimeOut(() => {
      fn()
      flag = true
    }, delay) 
  }
} // 短時(shí)間內(nèi)大量觸發(fā)同一事件,只會(huì)執(zhí)行一次,規(guī)定時(shí)間內(nèi)再次觸發(fā)會(huì)阻止執(zhí)行(技能冷卻)
  • 其他應(yīng)用場(chǎng)景: input搜索事件,頁(yè)面resize事件。
十二、原型和原型鏈
  • 構(gòu)造函數(shù)
  • 每個(gè)對(duì)象都有一個(gè)__proto__屬性,并且指向它的prototype原型對(duì)象
  • 每個(gè)構(gòu)造函數(shù)都有一個(gè)prototype原型對(duì)象,prototype原型對(duì)象里的constructor指向構(gòu)造函數(shù)本身
  • prototype對(duì)象相當(dāng)于特定類(lèi)型所有實(shí)例對(duì)象都可以訪(fǎng)問(wèn)的公共容器
十三、EventLoop
  • JS是單線(xiàn)程的,為了防止一個(gè)函數(shù)執(zhí)行時(shí)間過(guò)長(zhǎng)阻塞后面的代碼,所以會(huì)先將同步代碼壓入執(zhí)行棧中,依次執(zhí)行,將異步代碼推入異步隊(duì)列。
十四、new操作符的作用
  • 內(nèi)存中創(chuàng)造一個(gè)空對(duì)象
  • this指向這個(gè)內(nèi)存中的空對(duì)象
  • 根據(jù)定義的鍵值和傳入的參數(shù),依次給這個(gè)空對(duì)象添加上鍵值對(duì)
  • 返回這個(gè)新的對(duì)象

十五、Promise

// 手寫(xiě)Promise
十六、computed和watch
  • computed:簡(jiǎn)化模塊代碼,所依賴(lài)的屬性未變化時(shí),直接去緩存,緩存是基于它們 的響應(yīng)式依賴(lài)進(jìn)行緩存的。
  • watch:需要數(shù)據(jù)變化時(shí)執(zhí)行異步或開(kāi)銷(xiāo)較大的操作時(shí)。
  • 使用場(chǎng)景:computed:當(dāng)一個(gè)屬性受多個(gè)屬性影響的時(shí)候。watch:當(dāng)一條數(shù)據(jù)影響多個(gè)數(shù)據(jù)的時(shí)候
十七、v-for中的key的作用
  • 為了更高效的對(duì)比虛擬DOM中每個(gè)節(jié)點(diǎn)是否是同一個(gè)節(jié)點(diǎn),唯一標(biāo)識(shí)。
  • Vue判斷兩個(gè)節(jié)點(diǎn)是否為相同時(shí),主要是根據(jù)兩者的Key和元素類(lèi)型等,若無(wú)key則會(huì)認(rèn)為是兩個(gè)相同的節(jié)點(diǎn),會(huì)造成大量的dom更新操作。
18、父子組件通信
  • props、自定義事件$emit、Ref、provide和inject等
19、雙向數(shù)據(jù)綁定
  • vue實(shí)例創(chuàng)建時(shí),會(huì)對(duì)data中的屬性進(jìn)行遍歷,通過(guò)Object.defineProtety轉(zhuǎn)換為getter和setter且在內(nèi)部追中相關(guān)依賴(lài),在屬性被訪(fǎng)問(wèn)和修改的時(shí)通知變化。

20、nextTick:在下次DOM更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后使用$nextTick,則可以在回調(diào)中獲取更新后的DOM。

21、keep-alive的實(shí)現(xiàn):實(shí)現(xiàn)組件的緩存
  • Vue.js內(nèi)部將DOM節(jié)點(diǎn)抽象成一個(gè)個(gè)的VNode節(jié)點(diǎn),keep-alive組件的緩存也是基于虛擬節(jié)點(diǎn)的而不是直接存儲(chǔ)DOM結(jié)構(gòu)。它將滿(mǎn)足條件的組件在cache對(duì)象中緩存起來(lái),在需要重新渲染的時(shí)候再將vnode節(jié)點(diǎn)從cache對(duì)象取出并渲染。(include、exclude配置屬性)

  • router中 添加 meta: keepAlive標(biāo)識(shí)

  •   <keep-alive>
           <router-view v-if="$route.meta.keepAlive">
          <!-- 這里是會(huì)被緩存的視圖組件 -->
          </router-view>
      </keep-alive>
    
22、vuex、vue-router實(shí)現(xiàn)原理
  • vuex:狀態(tài)管理庫(kù)
    • state單一狀態(tài)樹(shù),getter、mutation顯示提交更改state
    • Action提交mutation,可以包含任意異步操作
    • module(當(dāng)應(yīng)用變的龐大復(fù)雜,拆分store為具體的module模塊)
23、vue中的diff算法和patch方法
  • patch:補(bǔ)丁,Vue更新時(shí)的patch算法,就是通過(guò)打補(bǔ)丁的形式充分利用原有的dom進(jìn)行增加,刪除和移動(dòng)操作,從而避免重新創(chuàng)建大量的dom操作,進(jìn)一步提升性能。
  • diff算法過(guò)程就是調(diào)用patch函數(shù);只能是同級(jí)比較。
  • 虛擬dom:是將真實(shí)dom的數(shù)據(jù)抽取出來(lái),以對(duì)象的形式模擬樹(shù)形結(jié)構(gòu)。
  • diff算法觸發(fā)過(guò)程: Vue的雙向綁定,是通過(guò)重置Object.defineProperty中的get和set方法進(jìn)行數(shù)據(jù)劫持,進(jìn)而觸發(fā)修改視圖操作。所以當(dāng)數(shù)據(jù)發(fā)生改變時(shí),set方法會(huì)調(diào)用Dep.notify通知訂閱者watcher,訂閱者就會(huì)調(diào)用patch方法給真實(shí)的dom打補(bǔ)丁,更新響應(yīng)的視圖。
24、Vue的性能優(yōu)化
  • 第三方模塊按需引入、防抖、節(jié)流、v-if替代v-show、圖片路由懶加載、異步組件
25、瀏覽器從輸入url到渲染頁(yè)面
  1. 網(wǎng)絡(luò):構(gòu)建請(qǐng)求、查找強(qiáng)緩存、DNS域名解析、建立TCP連接(三次握手)、發(fā)送HTTP請(qǐng)求
  2. 瀏覽器解析:解析html構(gòu)建DOM樹(shù)、解析CSS構(gòu)建CSS樹(shù)、樣式計(jì)算、生成布局樹(shù)
  3. 瀏覽器渲染:建立圖層樹(shù)、顯示器顯示內(nèi)容、斷開(kāi)連接(四次揮手)
26、http和https區(qū)別
  1. 默認(rèn)端口、安全性(明文傳輸、加密傳輸協(xié)議)
  2. http的連接無(wú)狀態(tài)的,https協(xié)議是ssl+http協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證網(wǎng)絡(luò)協(xié)議。
27、get和post區(qū)別
  1. post更安全、數(shù)據(jù)更大、發(fā)送數(shù)據(jù)類(lèi)型較多、速度較慢、用于修改和寫(xiě)入數(shù)據(jù)
  2. get 回退時(shí)是無(wú)害的,而post會(huì)再次提交請(qǐng)求
28、三次握手、四次揮手
  1. 多一次握手的必要性:防止已失效的請(qǐng)求報(bào)文突然又傳到了服務(wù)端而產(chǎn)生連接的誤判。
  2. 四次揮手:即中止TCP連接,需要客戶(hù)端和服務(wù)端總共發(fā)送四個(gè)包確認(rèn)連接的斷開(kāi)。
  3. 多一次揮手:a:在請(qǐng)求連接時(shí),服務(wù)端在收到建立連接請(qǐng)求的syn報(bào)文后,把a(bǔ)ck和syn放在一個(gè)報(bào)文里發(fā)送給客戶(hù)端。 b:關(guān)閉連接,當(dāng)收到對(duì)方的fin報(bào)文時(shí),僅代表對(duì)方不再發(fā)送數(shù)據(jù)但還能接收數(shù)據(jù),我們也未必把全部數(shù)據(jù)都發(fā)給了對(duì)方,所以我們可以立即close,也可以發(fā)送一些數(shù)據(jù)給對(duì)方,再發(fā)送fin報(bào)文給對(duì)方表示同意關(guān)閉連接。因此我們的ack和fin一般會(huì)分開(kāi)發(fā)送。
  4. ACK: 確認(rèn)序號(hào)有效;SYN:建立一個(gè)新的連接;FIN:釋放一個(gè)鏈接
29、http如何實(shí)現(xiàn)緩存:強(qiáng)緩存、協(xié)商緩存
  • 強(qiáng)緩存:Expirse(過(guò)期時(shí)間)、Cache-Control(no-cache)協(xié)商緩存
  • 瀏覽器會(huì)根據(jù)請(qǐng)求的信息判斷,強(qiáng)緩存是否命中,如果命中則直接使用資源,否則,根據(jù)頭信息向服務(wù)器發(fā)送請(qǐng)求,使用協(xié)商緩存,如果命中,則服務(wù)去器不返回資源,瀏覽器直接使用本地資源的副本,若不命中,則瀏覽器返回最新的資源給瀏覽器。
30、輸入url后http請(qǐng)求的完整過(guò)程
  • 建立TCP連接 - 發(fā)送請(qǐng)求行 - 發(fā)送請(qǐng)求頭 - 到達(dá)服務(wù)器(發(fā)送狀態(tài)行) - 發(fā)送響應(yīng)頭 - 發(fā)送響應(yīng)數(shù)據(jù) - 斷TCP連接
31、跨域方式
  • jsonp:利用script標(biāo)簽沒(méi)有跨域限制,缺點(diǎn):只支持get請(qǐng)求
  • CORS(設(shè)置Access-Control-Allow-Origin: 指定可訪(fǎng)問(wèn)資源的域名)
32、瀏覽器的本地存儲(chǔ):cookie、sessionStorage、localStorage
  • 都是保存在瀏覽器、且同源
  • 不同點(diǎn):
    • 存儲(chǔ)大小限制、作用域不同
    • cookie:在瀏覽器和服務(wù)器間來(lái)回傳遞(4K);其他僅在本地(5M);
33、常見(jiàn)的webpack loader
  • File-loader、image-loader、url-loader、css-loader、sass-loader、style-loader
34、javascript的繼承方式
  • 原型鏈繼承:子類(lèi)型的原型為父類(lèi)型的一個(gè)實(shí)例對(duì)象

    // 父
    function Father(name) {
      this.name = name || 10
    }
    Father.prototype.sayHi = function() { conosle.log('sayHi') }
    // 子
    function Son() {}
    Son.prototype = new Father()
    Son.prototype.sayHello = function() { console.log('sayHello') }
    
    let son = new Son()
    son.sayHi() // 'sayHi'
    son.sayHello() // 'sayHello'
    son.name // 10
    
    Object.getPrototypeOf(son) === son.__proto__ === Son.prototype
    
    
  • ES6中的Class繼承

    // 父類(lèi)
    class Father {
      constructor(age) {
        this.age = age
      }
      sayHi() { console.log('sayHi')}
    }
    // 子類(lèi)
    class Son extends Father{
      constructor(name, age) {
        super(age)
        this.name = name
      }
      sayHello() { console.log('sayHello')}
    }
    let son = new Son('xsk', 18)
    son.name // 'xsk'
    son.age // 18
    son.sayHi() // 'sayHi'
    son.sayHello() // 'sayHello'
    
35、call、apply和bind的區(qū)別
  • call和apply改變this指向;call的性能好一點(diǎn);省去了第二個(gè)參數(shù)解構(gòu)賦值
  • bind原理:返回一個(gè)函數(shù),另外兩個(gè)立即執(zhí)行
36、淺拷貝、深拷貝
  • JSON的弊端:序列化的結(jié)果會(huì)把函數(shù)或者undefined丟失; NaN、Infinity和-Infinity序列化后的值會(huì)變?yōu)閚ull; 值有時(shí)間對(duì)象會(huì)轉(zhuǎn)為字符串形式;有RegExp、Error對(duì)象,結(jié)果為空對(duì)象。
  • 弊端2:構(gòu)造函數(shù)實(shí)例的對(duì)象,拷貝后會(huì)丟棄對(duì)象constructor;對(duì)象中存在循環(huán)引用的情況也無(wú)法實(shí)現(xiàn)正確的深拷貝。
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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