前端面試小冊子

前端面試小冊

常考面試題一

一、原始類型有那種?nulll是對象嗎?

原始數據類型主要分爲:
number,string,Boolean,null,undefind
null是對象css

二、對象類型和基礎類型的不一樣之處,函數參數是對象類型和基礎類型分別會如何?

基礎類型按值儲存在棧內存中
對象類型(引用類型)儲存在堆內存中。以指針方式去使用
函數參數和複製操做:
基礎數據類型在從新建立一份新值。改變其中任何一個,另外一個不受影響
引用數據類型。變量對象也會爲其開闢空間,但複製的是指針,都指向內存的值,一個改變,另外一個也回受影響html

三、typeof 與 instanceof?

typeof 與 instanceof都是判斷數據類型的。區別以下:
typeof判斷基礎數據類型。當判斷null的時候將返回objcet
instanceof判斷引用數據類型,原理根據原型鏈追蹤去實現前端

四、類型轉換?

  • 轉數字?

    null=》0
    undefined=》NaN
    Boolean
    true =》1
    false=》0
    Sting
    數字=》數字
    字母=》NaN
    空字符串=》0
    數組
    空數組=》0
    一個元素且爲數字=》數字
    其餘=》NaN
    引用類型
    NaNnode

  • 轉字符串

    underfind=》‘underfind’
    null=》‘null’
    Number
    '數字'
    Boolean
    ‘true’
    ‘false’
    數組
    ‘【12.43,323】’=>12.43,323
    對象
    [object Object]
    function
    function(){console.log(212)}es6

  • 轉布爾值?

    null
    false
    underfind
    false
    Number
    0,-0,NaN=>false
    其餘=>true
    String
    ''=>false
    其餘=>true
    引用類型
    trueweb

五、對象轉基礎數據類型?

轉字符串類型直接調用toString()
轉其餘類型先轉valueOf()面試

六、四則運算?

運算中其中一方是字符串,另外一個方也將轉換成字符串
若是一方不是字符串數字。那麼會將它轉成數字或者字符串
除了加減運算以外。一方爲數字,另外一方轉爲數字算法

七、比較運算符?

若是是對象,就經過 toPrimitive 轉換對象
若是是字符串,就經過 unicode 字符索引來比較chrome

八、如何判斷this指向,箭頭函數中this指向那裏?

  • 全局this

    window數據庫

  • 函數中的this

    對象調用,則指向這個對象
    獨立調用,指向window

  • 使用call,apply顯示指定this

    apply.call,bind動態this

  • 構造函數與原型方法上的this

    指向當前實例化後的對象。

  • 箭頭函數中的this

    調用箭頭函數外層第一個普通函數的this

常考面試題二

==和===的區別?

  • ==

    先判斷數據類型是否相同,一致判斷值大小
    類型不一樣,進行類型轉換
    先判斷是不是null和underfind的比較,是返回true
    判斷是不是string和number的比較,是先將字符串轉成對應的數字進行比較
    判斷一方是否爲布爾值,是則把布爾值換成number進行比較
    判斷一方是否爲object,且另一方爲string,number,是則把object轉成基礎類型進行判斷

  • ===

    不會盡享類型轉換,直接對比值的大小

閉包

  • 什麼是閉包?

    在函數執行上下A
    在執行上下文A中的函數B
    調用了A中的變量。閉包產生

  • 閉包的好處?以及和垃圾回收機制的關係?

    在js中,函數上下文執行完以後,生命週期結束後。垃圾回收機制就會回收內部不被使用的變量,也就是內存中失去引用的變量,對其進行回收。閉包會阻止此過程
    js中具備自動垃圾回收機制,對於函數內部的變量失去引用以後,很快會被回收,可是處於全局的變量,js不會回收,除非引用完及時釋放,儘可能少使用全局變量

淺拷貝和深拷貝

  • 淺拷貝

    基礎類型值的拷貝
    引用類型拷貝的引用地址(指針)
    一個改變另外一個必受影響
    Object.assign()和...都是淺拷貝

  • 深拷貝

    從新開闢內存空間,互相不影響

    function deepClone(obj) {
            function isObject(o) {
                return (typeof o == 'object' || typeof o == 'function') && o !== null
            }
            if (!isObject(obj)) {
                throw new Error('this is not objcet')
            }
            let isArray = Array.isArray(obj)
            let newObj = isArray ? [...obj] : {
                ...obj
            }
            Reflect.ownKeys(newObj).forEach(key => {
                newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
            })
            return newObj
       }

原型鏈

對象的 __proto__ 屬性指向原型, __proto__ 將對象和原型鏈接起來組成了原型鏈

  • 構造函數
  • 原型
  • 原型

es6常考知識點

什麼是提高?什麼是暫時性死區?var、let 及 const 區別?

  • 提高

    當控制器執行到可執行的代碼的時候,js就會建立執行上下文
    執行上下文的建立階段會建立變量對象。此時
    此時會先建立arguments對象
    檢查函數,以函數聲明並建立屬性
    檢查var聲明的變量,複製underfind
    其實這個就是所謂的變量提高階段

  • var 、const、let的區別?

    區別:
    var存在變量提高
    能夠重複聲明
    能夠用window去調用
    const、let
    不存在變量提高
    不可重複聲明
    擁有塊級做用域
    不可經過window去調用
    const賦值不可更改

  • 暫時性死區

    當變量未聲明以前。去調用此變量,被叫作暫時性死區

原型如何實現繼承?Class 如何實現繼承?Class 本質是什麼?

  • 原型繼承

    • 組合繼承

      構造函數繼承經過
      call改變this指向去繼承上面的方法和屬性
      原型上的繼承
      將子類的原型指向父級的實例話對象

    • 寄生繼承

      構造函數繼承一樣使用call改變指向進行繼承
      原型繼承則經過Object.create()進行繼承

  • class繼承

    class 實現繼承的核心在於使用 extends 代表繼承自哪一個父類
    而且在子類構造函數中必須調用 super,由於這段代碼能夠當作 Parent.call(this, value)

  • class本質

    class 的本質就是函數。

爲何要使用模塊化?都有哪幾種方式能夠實現模塊化,各有什麼特色?

  • 模塊化的使用

    解決命名衝突
    實現複用
    提升代碼的可維護程度
    避免變量全局污染

  • 匿名函數自執行
  • ES Module

    不支持動態引入

Proxy 能夠實現什麼功能?

  • 對象的代理

    代理,但是實現數據的雙向綁定

    let handler = {
                get(target, property, receiver) {
                    getLogger(target, property)
                    return Reflect.get(target, property, receiver)
                },
                set(target, property, value, receiver) {
                    setBind(value, property)
                    return Reflect.set(target, property, value)
                }
            }
            return new Proxy(obj, handler)
        }
        let p = onWatch(
            obj,
            (v, property) => {
                console.log(`監聽到屬性${property}改變爲${v}`)
            },
            (target, property) => {
                console.log(`'${property}' = ${target[property]}`)
            }
        )
        p.a = 2 // 監聽到屬性a改變
        console.log(p.a)
  • 表單校驗
  • 閱後即焚
  • 過濾不存在的屬性

map, filter, reduce

  • map

    返回一個新數組。能夠在這個函數中加邏輯處理返回
    接受三個參數
    當前的元素
    index
    願數組

  • filter

    返回一個新數組。對符合條件元素進行返回
    接受三個參數
    當前的元素
    index
    願數組

  • reduce

    數組的計算
    接受兩個參數,分別是回調函數和初始值

性能優化瑣碎事

圖片優化

常考算法知識點

Vue 常考基礎知識點

生命週期

父子組建傳旨

設計模式

工廠模式

隱藏了這個複雜的過程,只須要一句代碼調用就能實現功能。

單例模式

隱藏了這個複雜的過程,只須要一句代碼調用就能實現功能。

適配器模式

適配器用來解決兩個接口不兼容的狀況,不須要改變已有的接口,經過包裝一層的方式實現兩個接口的正常協做。

class Man {
        getName() {
            return '港版插頭'
        }
    }
    class Son {
        constructor() {
            this.proxy = new Man()
        }
        getName() {
            return this.proxy.getName() + 'hahahahh'
        }
        static create(name) {
            console.log(name)
        }
    }
    let s = new Son()
    console.log(s.getName())

裝飾模式

代理模式

代理是爲了控制對對象的訪問,不讓外部直接訪問到對象。在現實生活中,也有不少代理的場景。好比事件代理

發佈-訂閱模式

發佈-訂閱模式也叫作觀察者模式。經過一對一或者一對多的依賴關係,當對象發生改變時,訂閱方都會收到通知。

外觀模式

JS 異步編程及常考面試題

併發(concurrency)和並行(parallelism)區別?

併發是一段時間相繼完成,好比A和B,一段時間內切換完成相似早上起牀前。洗漱,吃飯,出門。一段時間完成的一些事
並行是同時進行,好比邊看手機邊吃飯

什麼是回調函數?回調函數有什麼缺點?如何解決回調地獄問題?

當咱們異步請求成功時會在回調函數中寫咱們的邏輯。固然這裏的邏輯還涉及到進一步的請求,不斷嵌套就會出現回調地獄
回調函數缺點:
嵌套過深,耦合度高,不易維護
難以捕捉錯誤
不能使用try。。catch
使用Generator和promise以及async均可以

你理解的 Generator 是什麼?

自然的迭代器,能夠是遍歷停下來
可控制迭代器的函數,能夠暫停,也能夠選擇任什麼時候候恢復
使用場景:
抽獎
小遊戲
斐波那契數列

Promise 的特色是什麼,分別有什麼優缺點?什麼是 Promise 鏈?Promise 構造函數執行和 then 函數執行有什麼區別?

特色:
Promise三個狀態,padding,resolve和reject。狀態不可逆,一旦確認,沒法改變
Promise鏈:
經過then方法去傳遞執行,執行then方法以後會返回一個promise對象,來完成鏈式操做
構造函數和then函數執行有哪些區別?
構造函數內的內容當即執行。
then的函數當狀態改變在進行執行

async 及 await 的特色,它們的優勢和缺點分別是什麼?await 原理是什麼?

優化了promise鏈式調用,以同步的寫法去操做異步代碼
原理實際上是promise的語法糖,await 內部經過promise靜態方法Promise.resove()返回一個新的promise

setTimeout、setInterval、requestAnimationFrame 各有什麼特色?

JS 進階知識點及常考面試題

apply

Function.prototype.myApply = function (context, arr) {
            if (typeof this !== 'function') {
                throw new Error('error')
            }
            context = context || window
            context.fn = this
            let reslut;
            if (arr) {
                reslut = context.fn(...arr)
            } else {
                reslut = context.fn()
            }
            delete context.fn
            return reslut
        }

call

Function.prototype.myCall = function (context) {
            if (typeof this !== 'function') {
                throw new Error('error')
            }
            context = context || window
            context.fn = this
            let args = [...arguments].slice(1)
            let reslut = context.fn(...args)
            delete context.fn
            return reslut
        }

bind

Function.prototype.myApply = function (context, arr) {
            if (typeof this !== 'function') {
                throw new Error('error')
            }
            context = context || window
            context.fn = this
            let reslut;
            reslut = arr ? context.fn(...arr) : context.fn()
            delete context.fn
            return reslut
        }

new

function news() {
            let obj = new Object()
            let Constructor = [...arguments].shift()
            obj.__proto__ = Constructor.prototype
            let res = constructor.apply(obj, arguments)
            return typeof res === 'object' ? ret : obj
        }

instanceof

function instanceofs(left, right) {
            let prototype = right.prototype
            left = left.__proto__
            while (1) {
                if (left == null || left == undefined) {
                    return false
                }
                if (left == prototype) {
                    return true
                }
                left = left.__proto__
            }
        }

垃圾回收機制

v8實現了精確式GC,GC算法採用分代垃圾回收機制,所以。v8將內存(堆)分爲新生代和老生代兩部分

  • 新生代算法

    對象存活時間較短,使用 Scavenge GC 算法
    在新生代內存空間分爲2部分,分別是from空間和to空間,在這2個空間其中必然有一個是空閒的。新分配的對象會放到from空間,當from空間被佔滿的時候,新生代GC就會啓動,算法會檢查from空間的存活對象,將他們複製到to空間,其中失去存活的對象就會被銷燬,將複製完,from和to空間互換,

    • from空間
    • to空間
  • 老生代算法

    • 何時啓動標記清除算法?

      某一個空間沒有分塊時
      空間中被對象超過一段限制時
      空間不能保證新生代對象轉到老生代中
      這個時候遍歷堆中全部活的對象,在標記完成後,銷燬那些沒有標記的對象。

    • 標記整理算法

      清除對象後會形成堆內存出現碎片的狀況
      當碎片超過必定限制的時,會啓動壓縮算法。在壓縮過程當中,將活的對象像一端移動,直到全部對象都移動完成而後清理掉不須要的內存。

    • 何時對象會出現老生代算法中?

      新生代中的對象是否已經經歷過Scavenge算法。若是經歷過,會將新生代空間轉到老生代空間中
      當to空間的對象佔空間大小的25%,這樣狀況下。爲了避免影響內存分配。會將對象重新生代的空間轉老生代空間中

瀏覽器基礎知識點及常考面試題

跨域

  • 什麼是跨域?

    瀏覽器出與安全考慮。有同源策略。也就是當協議。域名。端口號任何一個不一樣就是跨域。Ajax就會請求失敗

  • 爲何瀏覽器要使用同源策略?

    其實主要是用來防止 CSRF 攻擊的。簡單點說,CSRF 攻擊是利用用戶的登陸態發起惡意請求。

  • 你有幾種方式能夠解決跨域問題?

    jsonp
    cors
    document.domain
    postMessage

  • 瞭解預檢請求嘛?

    對於複雜請求來講,首先會發起一個預檢請求,該請求是 option 方法的,經過該請求來知道服務端是否容許跨域請求。

事件

  • 事件處理程序

    • IE事件處理程序

      增長和和刪除事件:
      element.attachEvent('on'+事件類型,處理函數)
      element.detachEvent(‘on’+事件類型,處理函數)

    • chrome事件處理程序

      element.addEventListener('click',處理函數,是否冒泡)
      false(默認冒泡)
      true(捕獲)
      element.removeEventListener('click',處理程序,是否冒泡)
      同添加事件一致

  • 事件對象

    • IE事件對象

      cancelBubble =》默認值爲false,但設置true就能夠取消事件冒泡
      returnValue =》默認true,設置爲false,,就能夠取消事件的默認行爲
      srcElement =>事件目標
      type=>事件類型

    • chrome事件對象

      stopPropagation =》取消事件冒泡
      preventDefault  =》取消事件的默認行爲
      target  =>事件目標
      type=>事件類型

  • 事件代理

    若是一個節點中子節點是動態生成的,那麼子節點須要註冊事件的化應該註冊在父節點上
    好處:
    節省內存空間
    不須要給子節點註銷事件

  • 事件的觸發過程是怎麼樣的?知道什麼是事件代理嘛?

    事件觸發有三個階段:
    window往事件觸發傳播。遇到註冊的捕獲事件會觸發
    傳播到事件觸發時觸發註冊事件
    從事件觸發之處向window傳播。遇到註冊的冒泡會觸發
    從捕獲到目標階段再到冒泡的過程

    • 事件捕獲

      從上向下執行的一個過程
      Document=》html=》body=》div

    • 事件執行階段
    • 事件冒泡

      從當前事件觸發向上查找過程
      div=>body=>html=>document

存儲

cookie已經不建議存儲了,若是沒有大量數據存儲須要,使用localStorage和sessionStorage
對於不怎麼改變的數據存使用localStorage。不然使用sessionStorage

  • cookie

    做用:主要用於儲存用戶的登錄信息,
    生命週期:通常有服務器生成,能夠設置過時時間
    數據儲存大小:4k
    與服務端通訊:每次都會攜帶在headr中,對於請求性能影響

    屬性 做用
    value 若是用於保存登錄狀態,應加密,不能使用明文的用戶標示
    http-only 不能經過js訪問cookie,減小xss的攻擊
    secure 只能在協議爲https的請求中攜帶
    same-site 規定瀏覽器不能在跨域請求中攜帶cookie,減小CSRE攻擊
  • localStorage

    生命週期:除非被清理,不然一直存在
    數據存儲大小:5M
    與服務端通訊:不參與

  • sessionStorage

    數據生命週期:頁面關閉就清理
    數據存儲大小:5M
    與服務端通訊:不參與

  • indexDB

    數據生命週期:除非被清理,不然一直存在
    數據存儲大小:無限
    是否與服務端通訊:不參與

Service Worker

service worker是一段腳本,與web worker同樣,也在後臺運行,做爲一個獨立的線程。運行環境和普通腳本不一樣,因此不能直接參與web交互行爲。native app能夠作到離線使用,消息推送。後臺自啓動,service worker的出現爲了是web app 也有相似的能力

  • 使用場景

    • 後臺消息傳送
    • 網絡代理轉發請求。僞造響應
    • 離線緩存

      • 離線緩存
    • 消息推送

瀏覽器緩存機制

性能優化領域
緩存能夠說是性能優化中最簡單高效的一種方式了。他以最高減小網絡傳輸所帶來的損耗
數據請求:
網絡請求
後端處理
瀏覽器響應
直接使用緩存,而不發請求
或發起請求後端存儲的數據和前端一致,那麼就不必將數據回傳過來,這樣能夠減小響應數據

緩存位置

  • Service Worker

    優勢:
    它的緩存和其餘內建的緩存機制不一樣。它能夠由咱們自定緩存那些文件,如何匹配緩存,如何讀取緩存,而且緩存是持久性的

  • Memory Cache

    優勢:

    內存中的緩存。讀取內存中的數據比磁盤要快不少

    訪問過頁面以後,再次刷新頁面,能夠發現以前不少數據都來自內存緩存
    缺點:
    持續性短,隨着進程的釋放而釋放
    大文件通常都是不會儲存內存中,反之優先

  • Disk Cache

    優勢:
    儲存在硬盤中。覆蓋率基本是最大的,什麼均可以存入
    跟內存相比。容量和儲存時效性超級好

  • Push Cache

    儲存在會話中,一旦會話結束就會被釋放

緩存策略

  • 強緩存

    • Expires

      是HTTP/1的產物,表示資源的過時時間,並受限與本地時間。若是修改了時間,緩存失效

    • Cache-control

      出現於HTTP/1.1的產物,優先級比Expires要高
      該屬性能夠調整設置時間
      Cache-control能夠在請求頭或者響應中設置,而且能夠組合多種指令
      private=>響應能夠被客戶端緩存
      pablic=》能夠同被客戶端和代理服務器緩存
      no-cache=》資源會被緩存,但當即失效。下次發起請求會驗證是否過時

  • 協議緩存

    若是緩存過時了。就須要發起請求驗證資源是否更新,協議緩存能夠經過2個http-header實現:Last-Modified+ETag
    當瀏覽器發起請求驗證資源時,若是資源沒有作出改變,那麼服務器會返回304狀態嗎。而且更新緩存有效期
    若是資源有所改變,更新資源

    • Last-Modified

      表示本地文件最後更改的日期。If-Modified-Since會將last-Modified的值發送給服務器,詢問服務器在該日期更新後資源是否有變更,有更新,返回更新後的信息,反之,返回狀態碼
      弊端:
      若是是本地打開緩存文件,即便沒有對文件進行修改,但仍是會形成last-Modified的修改。服務端不能命中緩存致使發送相同的資源
      由於last-Modified只能以秒計時。若是在不可感知的時間你內完成了這個文件,那麼會形成服務端認爲資源被秒中,不會返回正確值

    • ETag

      相似指紋,If-None-Match會將ETag發送給你服務器,詢問服務器資源ETag是否改變,若有改變,將更新的資源返回來,ETag比Last-Modified的優先級高

瀏覽器渲染機制

瀏覽器接收到 HTML 文件並轉換爲 DOM 樹

首先瀏覽器打開一個網頁的時候,首先會解析他對應的html,在網絡傳輸中咱們平時所寫的js+css+html都都是以子節數據(0-1)進行傳輸
轉子節轉爲字符串。
字符串經過詞法解析爲標記(token),這一過程也被稱爲標記法。
將結束標記以後,將會把標記轉爲node
根據node以前的聯繫轉成dom

將 CSS 文件轉換爲 CSSOM 樹

首先這一過程是很是耗性能的,由於瀏覽器會肯定每個節點樣式分別是什麼,須要遞歸匹配到數據的變化
子節數據
字符串
標記(token)
node
cssom

生成渲染樹?

當咱們生成dom樹和cssom樹的時候,就須要將這2個樹和成渲染樹
在這一過程當中,將包括須要的節點和這些節點的樣式去渲染出來
當瀏覽器生成渲染樹以後,瀏覽器根據渲染樹佈局,而後GPU繪製。合成圖層

爲何操做 DOM 慢?

由於dom屬於渲染引擎,js屬於js引擎,面對兩個線程以前的通訊,操做dom次數一多,也就等同於進行線程以前的切換,而且操做dom可能帶來回流。

什麼狀況阻塞渲染?

渲染的前提是生成渲染樹,全部html和css確定會堵塞渲染
下降一開始須要渲染的文件大小
而且扁平化。優化選擇器
當瀏覽器在執行到script標籤時,就會暫時dom,完成後從暫停處繼續執行,
首評加載的越快,就不應在首評加載js。建議將script放到body下面的緣由
async(適合沒有依賴的文件)
js文件下載和解析不會阻塞渲染
defer
並行下載,會等到html執行完畢以後在進行執行

重繪(Repaint)和迴流(Reflow)

迴流必定會引發重繪
但重繪不必定會引發迴流

  • 重繪(Repaint)

    當改變節點的樣的時候。不會改變佈局的時候,好比修改color樣式。

  • 迴流(Reflow)

    通常佈局修改,dom操縱通常會觸發迴流

減小重繪和迴流的方式?

使用 transform 替代 top
使用 visibility 替換 display: none ,由於前者只會引發重繪,後者會引起迴流(改變了佈局)
不要把節點的屬性值放在一個循環裏當成循環裏的變量
不要使用 table 佈局,可能很小的一個小改動會形成整個 table 的從新佈局
動畫實現的速度的選擇,動畫速度越快,迴流次數越多,也能夠選擇使用 requestAnimationFrame
CSS 選擇符從右往左匹配查找,避免節點層級過多

不考慮緩存和優化網絡協議的前提下,考慮能夠經過哪些方式來最快的渲染頁面?

從文件大小
從script標籤上使用來考慮
從html和css代碼書寫上來考慮
從須要下載的內容是否須要在首屏使用上來考慮

安全防範知識點

xss

想盡一切辦法將可執行的代碼注入網頁中

  • 持久型攻擊

    攻擊的代碼被服務器寫日數據庫,這種危害會很大,若是網站訪問量大的話,會致使正常訪問頁面的用戶都收到攻擊
    通常會以評論方式去注入

  • 非持久型攻擊

    通常以修改URL參數的方式進行攻擊
    誘導用戶訪問連接從而實現攻擊

轉義字符

對於用戶輸入的東西永遠不要相信,最普通的作法是對用戶輸入的內容進行轉譯。
引號。尖括號。斜槓等進行轉譯‘
或者使用白名單也能夠,js-xss來實現

cors

跨站僞造請求,攻擊者構造出一個向後端請求的地址,誘導用戶點擊或者經過某種途徑自動發起請求,若是用戶是在登錄的狀況下,後端覺得是用戶操做,從而進行誘導。
經常使用方式:
加入網站中有個get請求提交表單的接口。那麼攻擊者會在釣魚網站加入一個圖片,圖片的地址就是這個評論的接口
防護:
get請求不對數據進行修改
不讓第三方訪問到用戶的cookie(some-site)
阻止第三方網站請求接口(驗證refrer)
請求是附帶驗證信息,好比token或者驗證碼,進行判斷

點擊劫持

攻擊者經過將要攻擊的網站經過iframe的方式放入本身的網站中,並將iframe設爲透明,誘導用戶點擊
防護:
js判斷,刪除頁面中的iframe

中間人攻擊

是指攻擊方同時將服務端和客戶端同時進行鏈接。並讓對方認爲都是安全的,但實際上整個過程當中,都是被控制了,攻擊者能夠同時修改用戶的信息和數據庫中的內容
防護:
儘可能避免在公衆場合使用Wi-Fi。避免被攻擊

v8下的js性能優化

XMind: ZEN - Trial Version

相關文章
相關標籤/搜索