面試題集錦

說明:剛經歷過面試不久,之前總是不總結的我,這回總結一下我常常遇到的面試題,留個回憶~
這裏只是作個簡單的介紹,給本身提個醒,根據面試題延伸出本身須要補哪一塊的知識。
下面,開始個人表演html

js有哪些內置對象?

本地對象和單體內置對象統稱爲「內置對象」前端

  • 本地對象(內置函數):
    Boolean / Number / String / Object / Array / Date / RegExp / Function / Error
  • 單體內置對象:Global/Math/Json(ECMAScript5新增)

js中使用typeof能獲得哪些類型?

undefined/number/string/boolean/object/functionvue

  • 值類型能詳細的區分出來
  • 引用類型區分不出來這麼詳細,只能區分出function
typeof undefined  // undefined
typeof 'abc'  // string
typeof 123  // number
typeof true  //  Boolean
typeof {}  // object
typeof []  // object
typeof null  // object
typeof console.log  // function

什麼時候使用=== 什麼時候使用==?

if (obj.a == null) {
    // 這裏至關於obj.a === null || obj.a === undefined的簡寫形式
    // jquery源碼推薦寫法
}

除了這個,其餘一概使用全等.java

JS變量按照存儲方式區分爲哪些類型,並描述其特色?

  • 值類型
    把數值分塊存儲在內存中,存儲在棧內存中node

  • 引用類型
    存儲在堆內存,變量只存了變量名和指針(用於找到堆內存的位置)jquery

如何理解JSON?

JSON只不過是一個JS對象,也是一種數據格式webpack

JSON.stringify({a: 10, b: 20})
JSON.parse("{"a": 10, "b": 20}")

數據格式:簡單值,對象,數組ios

JSON跟對象字面量的寫法很像,JSON屬性必須加雙引號。git

如何準確判斷一個變量是數組類型?

簡單判斷:es6

var arr = [];
arr instanceof Array  // true
typeof arr  // object。  typeof 是沒法判斷是不是數組

更準確的判斷:

function isArray(value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}
isArray([1, 2, 3]);

描述new一個對象的過程?

  • 建立一個新對象
  • this指向這個新對象
  • 執行代碼,即對this賦值
  • 返回this

實戰中原型使用實例?

function Elem(id) {
  this.elem = document.getElementById(id)
}
Elem.prototype.html = function(val) {
  var elem = this.elem;
  if (val) {
    elem.innerHtml = val;
    return this; // 鏈式調用
  } else {
    return elem.innerHtml;
  }
}
Elem.prototype.on = function(type, fn){
  var elem = this.elem;
  elem.addEventListener(type, fn);
  return this;
}
var div1 = new Elem('div1');
div1.html('<p>顯示出來了</p>').on('click', function() {
  console.log('ok');
  }).html('<p>kaopu</p>')

說一下對變量提高的理解?

變量定義和函數聲明(函數表達式)都會被提到前面,即變量提高。

什麼是單線程,和異步有什麼關係?

單線程:只有一個線程,同一時間只能作一件事,兩段JS不能同時執行
緣由:避免DOM渲染的衝突
解決方案:異步算是一種「無奈」的解決方案,雖然有不少問題
異步是單線程的解決方案

避免DOM渲染的衝突:

  • 瀏覽器須要渲染DOM
  • JS能夠修改DOM結構
  • JS執行的時候,瀏覽器DOM渲染會暫停
  • 兩段JS也不能同時執行(都修改DOM就衝突了)
  • webworker支持多線程,可是不能訪問DOM

異步存在的兩個問題:

  1. 沒有按照書寫方式執行,可讀性差
  2. callback中不容易模塊化

實現方式:event loop

  • 事件輪詢,JS實現異步的具體解決方案
  • 同步代碼,直接執行
  • 異步函數先放在異步隊列中
  • 待同步函數執行完畢,輪詢執行 異步隊列 的函數
  • 注意:當即放入,指定時間內放入,請求完成後放入

使用異步的場景

  • 定時任務:setTimeout,setInterval
  • 網絡請求:ajax請求,動態加載
  • 事件綁定

總結當前異步的解決方案

  • jQuery Deferred
  • Promise
  • Async/Await
  • Generator

同步和異步的區別
同步會阻塞代碼執行,而異步不會
alert是同步,setTimeout是異步

DOM節點的Attribute和property有什麼區別?

property只是一個js對象的屬性修改,它們會在初始化的時候再DOM對象上建立。
Attribute是對html標籤屬性的修改,attributes是屬於property的一個子集。

  • property可以從attribute中獲得同步;
  • attribute不會同步property上的值;
  • attribute和property之間的數據綁定是單向的,attribute->property;
  • 更改property和attribute上的任意值,都會將更新反映到HTML頁面中;

cookie: 自己用於客戶端和服務器端通訊,可是它有本地存儲的功能,因而就被「借用」,使用document.cookie = … 獲取和修改便可。
缺點:存儲量過小,只有4kb,全部http請求都帶着,會影響獲取資源的效率,API簡單,須要封裝才能用。

sessionStorage, localStorage:HTML5專門爲存儲而設計,最大容量5M,API簡單易用: localStorage.setItem(key, value) localStorage.getItem(key)
localStorage在IOS safari隱藏模式下,localStorage.getItem會報錯

sessionStorage關閉瀏覽器後數據也會跟着清掉,而localStorage不會。

區別:容量,是否會攜帶到ajax中,API易用性

AMD和CommonJS的使用場景

  • 須要異步加載JS,使用AMD,CommonJS是同步
  • 使用npm以後建議使用CommonJS

上線流程要點

  1. 將測試完成的代碼提交到git版本庫的master分支
  2. 將當前服務器的代碼所有打包並記錄版本號,備份
  3. 將master分支的代碼提交覆蓋到線上服務器,生成新版本

回滾流程要點

  1. 將當前服務器的代碼打包並記錄版本號,備份
  2. 將備份的上一個版本號解壓,覆蓋到線上服務器,並生成新的版本號

加載一個資源的過程

  1. 瀏覽器根據DNS服務器獲得域名的IP地址
  2. 向這個IP的機器發送http/https請求
  3. 服務器收到、處理並返回http/https請求
  4. 瀏覽器獲得返回內容

性能優化

  • 資源合併,減小http請求(經過構建工具合併, webpack或者gulp);
  • 靜態資源緩存(經過鏈接名控制);
  • 使用CDN, 減輕服務器端請求壓力;
  • 懶加載;
  • 減小DOM操做(緩存DOM查詢,合併DOM插入);
  • 事件節流.

class和js構造函數的區別

  1. Class語法上更加貼合面向對象的寫法,java發展方向
  2. Class實現繼承更加易讀、易理解
  3. 更易於寫java等後端語言的使用
  4. 本質仍是語法糖,使用prototype

es6經常使用的功能

  • Class
  • promise
  • import export 模塊化
    編譯:webpack rollup
  • let/const(常量)
  • 多行字符串/模板變量 ${}
  • 解構賦值 const {a, b} = {a: 10, b: 20, c: 30}
  • 塊級做用域
  • 函數默認參數
  • 箭頭函數

如何理解MVVM?

首先從名字來看,MVVM即Model, View ViewModel,Model對應的是data數據部分,View對應的是html視圖部分,ViewModel對應的是new Vue實例部分,View經過事件綁定的方式影響到Model,Model經過數據綁定影響到View。

對ViewModel的理解:鏈接器,用於鏈接View和Model

MVVM不是一個從零開始的創新,是由以前的MVC發展過來的,由於MVC是應用到後端的,並非前端的,爲了適用前端的場景,把C換成了VM

如何實現MVVM

MVVM實現的三要素也是vue的三要素:

  1. 響應式:vue如何監聽到data的每一個屬性變化?
  2. 模板引擎:vue的模板如何被解析,指令如何處理?
  3. 渲染:vue模板如何被渲染成html? 以及渲染過程?

設計模式的六大原則(SOLID)

  • 單一職責原則
  1. 一個程序只作好一件事
  2. 若是功能過於複雜就拆分開,每一個部分保持獨立
  • 開放封閉原則
  1. 對擴展開放,對修改封閉
  2. 增長需求時,擴展新代碼,而非修改已有代碼
  3. 這是軟件設計的終極目標
  • 李氏置換原則
  1. 子類能覆蓋父類
  2. 父類能出現的地方,子類就能出現
  3. JS中使用較少(弱類型&繼承使用較少)
  • 接口獨立原則
  1. 保持接口的單一獨立,避免出現「胖接口」
  2. JS中沒有接口(typescript例外),使用較少
  3. 相似於單一職責原則,這裏更關注接口
  • 依賴倒置原則
  1. 面向接口變成,依賴於抽象而不依賴於具體
  2. 使用方只關注接口而不關注具體類的實現
  3. JS中使用較少(沒有接口&弱類型)
  • 迪米特法則

去重 寫代碼消除 數組 【6 8 9 9 12 13 14 1 3】中重複的元素。

方法一:
let arr = [6, 8, 9, 9, 12, 13, 14, 1, 3];
function removeArr(arr) {
  let arrayResult = [];
  for (let i = 0, len = arr.length; i < len; i++) {
    if (arrayResult.indexOf(arr[i]) === -1) {
      arrayResult.push(arr[i]);
    }
  }
  return arrayResult;
}
removeArr(arr);
方法二:
var arr = [6, 8, 9, 9, 12, 13, 14, 1, 3];
function removeArr(arr) {
  var i = 0,
      len = arr.length,
      j;
  for (i; i < len; i++) {
    for (j= i+1; j < len; j++) {
      if(arr[i] == arr[j]) {
        arr.splice(j, 1);
        j--;
      }
    }
  }
  return arr;
}
removeArr(arr);
方法三:
let arr = [6, 8, 9, 9, 12, 13, 14, 1, 3];
function removeArr(arr) {
  return Array.from(new Set(arr))
}
removeArr(arr);
方法四:
let arr = [6, 8, 9, 9, 12, 13, 14, 1, 3];
function removeArr(arr) {
  let arrayResult = [];
  arr.reduce((s1, s2) => {
    if(s1 !== s2) {
      arrayResult.push(s1);
    }
    return s2
  });
  arrayResult.push(arr[arr.length-1])
  return arrayResult;
}
removeArr(arr);

ajax和axios的區別, fetch

  1. jQuery整個項目太大,單純使用ajax卻要引入整個jQuery很是不合理
  2. axios是Promise的實現版本,符合最新ES規範,支持Promise API
  3. axios客戶端支持防止XSRF
  4. axios提供了一些併發的請求接口

fetch:
號稱是AJAX的替代品.。

優點:

  • 更加底層,提供的API豐富(request, response)
  • 脫離了XHR,是ES規範裏新的實現方式

缺點:

  1. fetch只對網絡請求報錯,對400,500都當作成功的請求,須要封裝去處理
  2. fetch默認不會帶cookie,須要添加配置項
  3. fetch不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實現的超時控制並不能阻止請求過程繼續在後臺運行,形成了流量的浪費
  4. fetch沒有辦法原生監測請求的進度,而XHR能夠

Vue生命週期

  • beforeCreate和created在vue實例化的時候就執行了,此處可請求數據,可是不能進行dom操做,由於拿不到組件對應的dom節點,以下圖。
    給實例賦值最先要在created裏面操做。

  • beforeMount和mounted這裏是把組件生成的html內容掛在到dom上面的一個過程,若是不指定el或者是$mount()的話,數據是不會掛在到頁面上的,由於它不知道該掛載到哪裏去。因此dom應該在mounted這裏纔去操做。
    beforeMount()是渲染前的,mounted()是經過render函數渲染後拿到的,mounted以後實例就建立完成了.
    說明:上述4個鉤子都是隻會被調用一次。beforeMount和mounted在服務端渲染的時候不會被調用。服務端渲染的時候會調用的只有beforeCreate和created。
    在.vue文件裏開發的過程當中,是都沒有template的,在.vue裏面寫的template都通過vue-loader處理直接變成了render函數放在vue-loader解析過的文件裏面。

  • beforeUpdate和updated是有數據更新的時候纔會去執行的。

  • beforeDestroy和destroyed組件被銷燬的時候纔會去執行。
    $destroy() // 組件銷燬的一個方法,解除全部的事件監聽和全部的watch。

  • activated和deactivated和keep-alive有關係,該鉤子在服務器端渲染期間不被調用。activated是在keep-alive 組件激活時調用。
    deactivated在keep-alive 組件停用時調用。

  • render(h)和renderError(),有render的時候就不須要template了,由於template處理後最終也是變成render函數的返回vnode的,renderError是在render報錯以後纔會觸發,報錯以後渲染出來的就是報錯的信息,只有在本組件的render函數出現錯誤的時候纔會被調用,只關心本身有沒有渲染成功,無論子組件。

  • errorCaptured() 正式環境可使用,收集線上環境的一些錯誤。全部子組件的錯誤均可以捕捉到,除非子組件把冒泡事件中止掉。

相關文章
相關標籤/搜索