2019年前端面試題目總結

haqiu發表於2019-03-12

CSS

1. css佈局,實現頂部高固定,左側導航寬固定,右側自適應

點我ԅ(¯﹃¯ԅ)

2. 三大定位,相對定位放在固定定位產生什麼影響?

fixed、relative、absolute

相對定位和固定定位,都會使塊級元素產生BFC,下面通過步驟檢測一下

  1. 設定父元素為固定定位,不設定高度,內部box設定高度和寬度,根據BFC內部box垂直排列的特徵,效果如下

    2019年前端面試題目總結

    <div class="sj">
        <div>1</div>
    </div>
    複製程式碼
    .sj{
        position: fixed;
        top: 0;
        left: 0;
        width: 200px;
        background-color: #ccc;
      }
      .sj>div{
        height: 20px;
        width: 100px;
        background-color: #2db7f5;
      }
    複製程式碼
    1. 若將內部box設為絕對定位,即內部box會產生BFC,根據BFC與外部互不影響的特徵,內部box將無法撐起父元素高度,如下

    2019年前端面試題目總結

    .sj>div{
        height: 20px;
        width: 100px;
        position: absolute;
        background-color: #2db7f5;
    }
    複製程式碼

3. 偽類和偽元素

偽類:向某些選擇器設定特殊效果,用於選擇器選擇不到的元素

偽元素:向某些選擇器新增特殊效果

  • 偽類本質為了彌補選擇器的不足,以此獲取更多資訊
  • 偽類建立一個新的虛擬容器,該容器內不包含dom節點,但可以新增內容,並且可對偽元素追加樣式
  • 偽類“:”,偽元素“::”
  • 可以同時使用多個偽類,但同時只能使用一個偽元素

4. 純css畫三角形

點我ԅ(¯﹃¯ԅ)

5. CSS BFC是什麼?

BFC是一個獨立的塊級渲染容器,擁有自己的渲染規則,不受外部影響,不影響外部

特徵

  1. 內部box垂直往下排列
  2. 受maigin特徵的影響,上下外邊距會塌陷
  3. BFC區域不會遮蓋浮動元素區域
  4. 計算BFC高度時,浮動元素高度也計算在內
  5. BFC是獨立渲染容器,外部元素不影響內部,反之亦然

產生條件

  1. 固定定位和絕對定位
  2. float除了none外
  3. overflow除了visible外(hidden、auto、scroll)
  4. display為以下其一(inline-block、table-cell、table-caption)

作用

  1. 清除浮動
  2. 消除margin重疊
  3. 佈局(左浮動,右BFC自適應)

6. 清除浮動的方式

1. 父元素設定偽類:clear:both + zoom:1

設定zomm為了相容IE

<div class="parent1 clearFloat">
    <div class="left"></div>
</div>
<div class="parent2"></div>

.parent1{
    border: 1px solid red;
}
.parent2{
    height: 100px;
    border: 1px solid blue;
}
.left{
    width: 200px;
    height: 200px;
    background-color: #5cadff;
    float: left;
}
.clearfloat::after{
    display: block;
    clear: both;
    content: '';
    visibility: hidden;
    height: 0;
}
.clearfloat {
    zoom: 1
}
複製程式碼

2. 結尾處新增空白標籤:claer:both

<div class="parent1">
    <div class="left"></div>
    <div class="clearfloat"></div>
</div>
<div class="parent2"></div>

.clearfloat{
    clear: both;
}
複製程式碼

3. 父元素產生BFC

BFC內浮動元素高度計算在內

7. 水平垂直居中的實現方式,儘可能多

方法一、定位 + transform

.parent{
    height: 500px;
    width: 500px;
    border: 1px solid red;
    position: relative;
 }
 .child{
    height: 80px;
    width: 80px;
    background-color: #515A6E;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
 }
複製程式碼

方法二、margin + transform

.parent{
    height: 500px;
    width: 500px;
    border: 1px solid red;
 }
 .child{
    height: 80px;
    width: 80px;
    background-color: #515A6E;
    margin: 50% 0 0 50%;
    transform: translate(-50%, -50%);
 }
複製程式碼

方法三、定位 + 負margin

.parent{
    height: 500px;
    width: 500px;
    border: 1px solid red;
    position: relative;
 }
 .child{
    height: 80px;
    width: 80px;
    background-color: #515A6E;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -40px 0 0 -40px;
 }
複製程式碼

方法四、flex

.parent{
    height: 500px;
    width: 500px;
    border: 1px solid red;
    display: flex;
    align-items: center;
    justify-content: center;
 }
 .child{
    height: 80px;
    width: 80px;
    background-color: #515A6E;
 }
複製程式碼

方法五、table-cell

.parent{
    height: 500px;
    width: 500px;
    border: 1px solid red;
    display: table-cell;
    text-align: center;
    vertical-align: middle;
 }
 .child{
    display: inline-block;
    height: 80px;
    width: 80px;
    background-color: #515A6E;
 }
複製程式碼

8. 盒子模型

標準盒子模型

width = content

IE盒子模型

width = border + padding + content

9. 塊級元素和行內元素的區別?img可設定寬高嗎?

塊級元素

  • 獨佔一行,在預設情況下,其寬度自動填滿其父元素的寬度
  • 塊級元素可以設定width、height屬性
  • 塊級元素即使設定了寬度也是獨佔一行,塊級元素可以設定margin、padding屬性

行內元素

  • 行內元素不會獨佔一行,相鄰的行內元素會排列在同一行裡,直到行排不下,就自動換行,其寬度隨內容而變化
  • 行內元素的width、height屬性則無效
  • 水平方向的padding、margin會產生邊距效果,豎直方向的padding、margin不會產生邊距效果

行內建換元素

瀏覽器依據元素的標籤和屬性來決定元素的具體顯示內容

img、input、textarea、select、object屬於行內建換元素, 具有塊級元素的特徵(除寬度外)

10. absolute定位 不設定top、right、bottom、left有什麼效果?

元素脫離文件流,但因為沒有設定屬性導致無法具體定位,緊跟在上個元素之後,但下個元素排列時會忽略此元素

2019年前端面試題目總結

JavaScript

1. js輸出陣列中出現最多的元素和次數

點我ԅ(¯﹃¯ԅ)

2. 100階臺階一次走1步或2步有多少種走法

假設只走一個臺階,有1種走法;兩個臺階,2中走法,三個臺階,3種走法;四個臺階,5種走法...

1->1; 2->2; 3->3; 4->5...可以看出此問題是斐波那契數列,即下個值是前兩個值的和

公式為:f(n) = f(n-1) + f(n-2)

方法一、遍歷相加

function test (num) {
    let num1 = 1, num2 = 2, res = 0
      for (let i=2; i<num; i++) {
        res = num1 + num2
        num1 = num2
        num2 = res
      }
    return res
}
複製程式碼

方法二、遞迴 (不推薦)

function test (num) {
    if (num === 1)
        return 1
    else if (num === 2)
        return 2
    else 
        return test(num-1) + test(num-2)
}
複製程式碼

3. 如何實現抽獎轉盤

4. 閉包及使用場景

  • 閉包

    1. 外部函式能夠訪問內部函式的變數
    2. 閉包所在的函式變數不能被垃圾回收機制回收
    3. 常駐記憶體,佔用記憶體使用量
  • 使用場景

    1. 給物件設定私有變數並且利用特權方法去訪問私有屬性
    2. 採用函式引用方式的setTimeout呼叫
    3. 封裝相關功能集

    ?傳送門

5. 什麼是原型、原型鏈?

  • 原型物件也是普通的物件,是物件一個自帶隱式的__proto__屬性,原型也有可能有自己的原型,如果一個原型物件的原型不為null的話,我們就稱之為原型鏈。
  • 原型鏈是由一些用來繼承和共享屬性的物件組成的(有限的)物件鏈。

6. 類的建立與繼承

  • 建立:new 一個Function,在prototype中新增屬性和方法
  • 繼承:
    1. 原型鏈繼承,基於原型鏈,是父類和子類的例項,無法實現多繼承
    function Cat(){}
    Cat.prototype = new Animal();
    Cat.prototype.name = 'cat';
    //&emsp;Test Code
    var cat = new Cat();
    複製程式碼
    1. 建構函式繼承:複製父類的例項給子類,只繼承父類例項的屬性與方法,不繼承原型上的,可實現多繼承
    function Cat(name){
        Animal.call(this)
        this.name = name || 'Tom';
    }
    var cat = new Cat()
    複製程式碼
    1. 組合繼承(原型鏈繼承+建構函式繼承)

7. new做了什麼事

  • 建立一個空物件
  • 將該物件的原型指向建立該物件的建構函式的prototype上

8.建立物件的方式

  1. 工廠模式
  2. 建構函式模式
  3. 原型模式
  4. 混合建構函式與原型模式

9. 深拷貝

  • 陣列的深拷貝
 let newArr = JSON.Parse(JSON.Stringify(oldArr))
複製程式碼
擴充套件運算子
let newArr = [...oldArr]
複製程式碼
  • 物件的深拷貝
function deepClone (obj) {
    let newObj = obj instanceof Array ? [] : {}
    for(var i in obj){
        newObj[i] = typeof obj[i] == 'object' ? deepClone(obj[i]) : obj[i]
    }
    return newObj
}
複製程式碼

webpack

webpack是模組打包工具,對js模組和擴充套件語言進行打包供瀏覽器識別執行

  • webpack只能處理js程式碼,其他格式需要通過loader進行轉換
  • 可對瀏覽器不能識別的規範和靜態檔案進行分析、壓縮、合併、打包成可供瀏覽器支援的程式碼

1. webpack和Grunt以及Gulp相比有什麼區別

2. webpack 的 loader 和 plugin 區別,舉幾個常用的 loader 和 plugin 並說出作用

  • loader用於對模組程式碼進行轉換,可將不同格式語言轉換為JavaScript,或將影象轉換為Data Url,由於webpack只能夠識別JavaScript,所以不同型別的模組需要對應的loader進行轉換
  • plugin是webpack的擴充套件外掛,可完成loader無法完成的複雜功能,可控制webpack每個打包環節的流程,極大豐富了webpack的擴充套件性

3. webpack打包過程

  • 讀取檔案,分析模組的依賴
  • 對模組進行解析執行(深度遍歷)
  • 針對不同的模組使用不同的 loader
  • 編譯模組,生成抽象語法樹(AST)
  • 遍歷 AST,輸出 JS

4. webpack打包優化

  • 使用compression-webpack-plugin壓縮程式碼
  • 使用cdn引入第三方庫
  • 按需引入第三方庫裡不同元件

Vue

1. 兄弟元件如何通訊,無巢狀,回撥觸發

方法一、通過父元件通訊

此方法需要保證兄弟元件A、B都在同一個父元件下;

父元件通過接受子元件A傳遞過來的事件訊息,並呼叫子元件B

子元件A
this.$emit('transmit', 'msg')
複製程式碼
父元件
<ChildA @transmit="transmit"></ChildA>
<ChildB :msg="msg"></ChildB>

transmit (data) => {
    this.msg = data 
}
複製程式碼
子元件B、需要使用watch來監聽父元件props穿過來的資料變化
watch (new, old) {
    資料操作... 
}
複製程式碼

方法二、eventBus

通過建立Bus.js註冊一個全域性例項,通訊元件通過呼叫例項的方法達到通訊目的

  1. 建立Bus.js
// eventBus 共享vue例項,用於兄弟元件資料傳遞
import Vue from 'vue'
const Bus = new Vue({})
export {Bus}
複製程式碼
  1. 元件A匯入Bus.js 並emit訊息
import {Bus} from './Bus.js'

Bus.$emit('transmit', 'msg')
複製程式碼
  1. 元件B匯入Bus.js並在mounted中檢測資料變化
import {Bus} from './Bus.js'

mounted () {
    Bus.$on('transmit', (data) => {
        操作...
    })
}

由於$on事件無法主動銷燬,所以需要根據業務手動進行銷燬

在元件銷燬前方法中銷燬
beforeDestory () {
    Bus.$off('transmit')
}

或者在使用前進行銷燬
mounted () {
    Bus.$off('transmit')
    Bus.$on('transmit', (data) => {
        操作...
    })
}
複製程式碼

2. vueRouter的工作原理

Vue Router 是路由管理器,可以改變url而不向伺服器傳送請求

有hash和history兩種路由模式

hash模式通過#之後的hash匹配路由元件;history通過url模擬hash匹配路由元件

3. Vuex的理解

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式

Vuex包含五個屬性:state、getter、mutation、action、module

  • state:儲存資料,儲存狀態;註冊了Store例項後,可通過this.$store.XX來訪問;對應元件內的data,資料為響應式,元件通過store來讀取vuex的資料,若資料改變,則元件的資料也會改變
  • getter:store的計算屬性,它的返回值會被依賴快取起來,當依賴值發生變化時才會被重新計算
  • mutation:更改Vuex的store中狀態的唯一方法是提交mutation
  • action:包含任意非同步操作,通過提交 mutation 間接更變狀態
  • module:將 store 分割成模組,每個模組都具有state、mutation、action、getter、甚至是巢狀子模組

當元件進行資料修改的時候,通過呼叫dispatch來觸發actions裡面的方法,actions裡每個方法都有commit方法,通過執行commit方法來觸發mutation裡的方法進行資料修改,由於mutation裡每個函式都有一個state引數,進而可對state進行修改,當資料修改完畢後,會傳導給頁面。頁面的資料也會發生改變。

4. vue Dom渲染的過程和原理

  • new Vue 初始化Vue例項
  • 通過三種渲染模式 Render、el、template 生成Render函式
  • 通過Watcher監測資料變化
  • 當資料變化時,通過Render函式生成VNode
  • 通過patchVnode對比前後變化,通過diff進行更新、新增、刪除等操作生成真實Dom節點

2019年前端面試題目總結

5. watch用法

watch用來監聽並響應資料的變化

  • 可以直接監聽基本資料型別資料
  • 若是監聽物件,則需要開啟deep(深度監聽)
  • 若是監聽陣列,則不需要開啟deep監聽
  • immediate 初始化繫結值時即執行監聽
  • watch首次初始化繫結不執行,但監聽的值發生變化時則執行監聽
data () {
    return {
        age: 20,
        obj: {
            age: 24
        },
        arr: [1,2,3]
    }
}
複製程式碼
1. 監聽基本型別
watch: {
    age (newd, oldd) {
        ...
    }
}

複製程式碼
2. 監聽物件
watch: {
    obj: {
        handler (newd, oldd) {
            ...
        },
        deep: true, // 開啟深度監聽
        immediate: true // 首次即執行
    }
}
複製程式碼
3. 監聽物件某個屬性

*** 採用字串
watch: {
    'obj.age': {
        handler (newd, oldd) {
            ...
        }
    }
}

*** 利用computed計算屬性
computed: {
    age () {
        return this.obj.age
    }
}
watch: {
    age (newd, oldd) {
        ...
    }
    // 也可寫為
    age: {
        handler (newd, oldd) {
            ...
        }
    }
}
複製程式碼

6. vue nextTick

非同步更新佇列

Vue 非同步執行 DOM 更新。只要觀察到資料變化,Vue將開啟一個佇列,並緩衝在同一事件迴圈中發生的所有資料改變。如果同一個 watcher被多次觸發,只會被推入到佇列中一次。這種在緩衝時去除重複資料對於避免不必要的計算和 DOM 操作是非常重要的。然後,在下一個的事件迴圈“tick”中,Vue重新整理佇列並執行實際 (已去重的) 工作。Vue 在內部嘗試對非同步佇列使用原生的Promise.then和MessageChannel,如果執行環境不支援,會採用 setTimeout(fn, 0) 代替。

例如,當你設定 vm.someData='newvalue',該元件不會立即重新渲染。當重新整理佇列時,元件會在事件迴圈佇列清空時的下一個“tick”更新

nextTick

由於DOM是非同步執行更新的,有時我們修改完資料等待DOM更新後進行操作,則此刻可使用Vue.nextTick(callback)

Vue.component('example', {
  template: '<span>{{ message }}</span>',
  data: function () {
    return {
      message: '沒有更新'
    }
  },
  methods: {
    updateMessage: function () {
      this.message = '更新完成'
      console.log(this.$el.textContent) // => '沒有更新'
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => '更新完成'
      })
    }
  }
})
複製程式碼

因為 $nextTick() 返回一個 Promise 物件,所以你可以使用新的ES2016async/await語法完成相同的事情:

methods: {
  updateMessage: async function () {
    this.message = 'updated'
    console.log(this.$el.textContent) // => '未更新'
    await this.$nextTick()
    console.log(this.$el.textContent) // => '已更新'
  }
}
複製程式碼

7. vue 生命週期有哪些?

  • beforeCreate ----建立前
  • created ---- 成功建立
  • beforeMount ---- 掛載前
  • mounted ---- 成功掛載
  • beforeUpdate ---- 更新前
  • updated ---- 成功更新
  • beforeDestroy ---- 銷燬前
  • destroyed ---- 成功銷燬

?傳送門,Vue宣告週期詳解

8. vue 響應式資料是如何實現的?

網路

1. 瀏覽器輸入地址後發生什麼

  1. 解析URL
  2. DNS解析、監測快取
  3. 客戶端與服務端建立TCP連線(三次握手)
  4. 請求與傳輸資料
  5. 進行資料渲染
  6. 解析HTML、生成DOM樹、解析CSS程式碼、將資料渲染到網頁上

2. 輪詢、長連線、websocket區別

  • 輪詢:每間隔規定時間,向伺服器傳送ajax請求,無需等待響應
  • 長連線:每次傳送完請求後,等待response後再傳送請求
  • websocket:h5提供的基於TCP的雙向通訊協議,伺服器主動推送訊息到客戶端,只需一次握手連線,即可建立持久連線

3. 三次握手、四次分手

  • 三次握手
    客戶端      ->(建立連線)->          伺服器
    客戶端   <-(確認接受,建立連線)<-   伺服器
    客戶端      ->(確認接受)->          伺服器
複製程式碼
  • 四次分手
    客戶端      ->(關閉連線)->      伺服器
    客戶端      <-(確認關閉)<-      伺服器
    客戶端      <-(關閉連線)<-      伺服器
    客戶端      ->(確認關閉)->      伺服器
複製程式碼

4. 請求狀態碼

  • 2XX 請求成功(200 請求成功、204 請求成功,但未有任何資源返回、206 範圍請求)
  • 3XX 重定向(301 url已更新、302 url重定向、303 是否訪問新的url、304 資源找到,不符合條件)
  • 4XX 客戶端錯誤(401 需要驗證、403 不允許訪問)
  • 5XX 伺服器錯誤

5. 如何防禦XSS攻擊

xss(跨站指令碼攻擊)攻擊是在返回的html中嵌入js指令碼

  • 需要在http頭部加上set-cookie httponly(禁止js訪問cookie) secure(在https時傳送cookie)

6. ajax請求過程

  1. 建立XMLHttpRequest物件,
  2. 建立http請求,並指明請求的url,方式和引數
  3. 設定http請求狀態變化的函式
  4. 傳送http請求
  5. 通過回撥獲取返回的資料
  6. 渲染

相關文章