js高頻面試題,整理好咯

中級前端面試題,不低於12k,整理的是js較高頻知識點,可能不夠完善,你們有興趣能夠留言補充,我會逐步完善,若發現哪裏有錯,還請多多斧正,哈哈前端

http和瀏覽器相關知識點,已分離出,會在下篇整理程序員

 黑寡婦

 

 

數據類型es6

基本類型:Number,String,Boolean,Null,Undefined面試

引用類型:Array,Function算法

 

基本類型和引用類型的區別數組

引用類型值保存在堆裏,基本類型是存放在棧裏瀏覽器

引用類型值可添加屬性和方法,而基本類型值則不能夠緩存

 

判斷類型方式安全

  1. typeof
  2. instanceof
  3. Object.prototype.toString.call()

 

棧和堆的區別閉包

  1. 棧由編譯器自動分配釋放空間,堆通常由程序員分配釋放
  2. 棧存放在一級緩存中,調用完畢當即釋放;堆則是在二級緩存中,生命週期由虛擬機的垃圾回收算法來決定

 

數組經常使用方法

改變原數組

  1. shift:刪除第一個元素
  2. unshift:向數組開頭添加元素
  3. pop:刪除最後一個元素
  4. push:向數組末尾添加元素
  5. reverse:數組倒序排序
  6. sort:數組正序排序
  7. splice: splice(start,length,item)刪,增,替換數組元素

不改變原數組

  1. concat:鏈接多個數組
  2. join:將數組全部元素以字符分隔
  3. slice:slice(start,end),切割數組
  4. map,filter,some,every等不改變原數組

 

數組排序

  1.  reverse()倒序
  2. sort()正序
  3. 冒泡排序
var arr = [1, 9, 4, 50, 49, 6, 3, 2];

function test(){

for (var i = 0; i < arr.length - 1; i++){

for (var j = i + 1; j < arr.length; j++){

var tempi = arr[i]; // 獲取第一個值,並與後一個值比較

var tempj = arr[j];

      if (tempi > tempj){

        arr[i] = tempj;

        arr[j] = tempi; // 若是前一個值比後一個值大,那麼相互交換

      }

    }

}

console.log(arr); // return arr

}

test(arr);  // [1, 2, 3, 4, 6, 9, 49, 50]

 

 

數組去重

  1. indexOf()  用for循環遍歷數組,把等於-1的值push進新建的空數組裏
  2. es6的set()方法
var arr = [1,1,12,12,13,13,8,8,9,7,5];

var arr2 = [...new Set(arr)]; // [1, 12, 13, 8, 9, 7, 5]

 

 

淺拷貝與深拷貝

深拷貝和淺拷貝只針引用類型(Object、Array)的數據

拷貝只複製指向某個對象的指針,而不復制對象自己,新舊對象共享同一內存,修改新對象會改變原對象

深拷貝則另外創造個如出一轍的對象,新舊對象不共享內存,修改新對象不會改到原對象

淺拷貝實現方法

  1. Object.assign() // 注意,當object只有一層結構,是深拷貝
  2. Array.prototype.concat()
  3. Array.prototype.slice()

深拷貝實現方法

  1. JSON.parse(JSON.stringify())
  2. 遞歸法,for循環遍歷對象、數組直到裏邊都是基本數據類型,而後再去複製

 

JSON.stringify()實現深拷貝的缺點

  1. 如obj裏有時間對象,則JSON.stringify(序列化)再JSON.parse(反序列化)後,時間對象將變成字符串形式,而不是對象形式
  2. 如obj裏有正則(RegExp)、Error對象,則序列化後只獲得空對象
  3. 如obj裏有函數,undefined,則序列化後會丟失
  4. 如obj裏有NaN、正無窮(Infinity)和負無窮(-Infinity),則序列化後會變成null

 

null,undefined的區別
null用來表示還沒有存在的對象

undefined表示"缺乏值",就是此處應該有一個值,可是尚未定義

 

函數聲明與函數表達式

在js中,解析器會率先讀取函數聲明,並使其在執行任何代碼前可用(可訪問)

而函數表達式,則必須等到解析器執行到它所在的代碼行,纔會真正被解析執行

 

原型鏈

函數對象

在JS中,函數即對象

原型對象 

定義函數對象時,會包含一個預約義屬性prototype,稱爲原型對象

__proto__

建立對象時,會有個[[proto]]內置屬性,用於指向建立它的函數對象的prototype,prototype也有[[proto]]屬性,在不斷指向中,造成了原型鏈

 

原型鏈的終點

原型鏈終點是null

 

原型鏈終點爲何是null

原型鏈上全部節點都是對象,不能是字符串、數字、布爾值等原始類型

另外,規範要求原型鏈必須是有限長度

 

new操做符具體作了什麼

  1. 建立空對象,this引用該對象,同時繼承該對象的原型
  2. 屬性和方法被加入到this引用的對象中

 

this指向問題

當沒有被對象調用時,指向window

當被對象調用時,指向調用他的對象

當實例化對象就在對象中時,指向該實例化對象

 

判斷空對象方法

  1. JSON.stringify(obj)

// 判斷JSON.stringify(data) == "{}"

  2. Object.keys(obj)

// 返回自身的可枚舉屬性

// 判斷Object.keys(data).length === 0

 

閉包

閉包就是可以讀取其餘函數內部變量的函數

 

閉包優勢

  1. 將變量長期保存,不被垃圾回收機制回收
  2. 避免全局變量的污染
  3. 安全性提升

 

閉包缺點

容易形成內存泄漏

 

閉包應用場景

  1. 封裝私有變量
  2. 經過閉包實現setTimeout傳參
  3. 做爲回調函數綁定到事件

 

常見內存泄漏

  1. 閉包
  2. 全局變量,至關於掛載到 window 對象上
  3. 被遺忘的定時器和回調函數

 

垃圾回收機制

  1. 標記清除
  2. 引用計數

 

事件冒泡

當元素接收事件時,會把接收的事件傳遞給本身的父級,層層傳遞直到window

 

阻止事件冒泡

IE瀏覽器: e.cancelBubble = true

其餘: e.stopPropagation()

 

事件捕獲

用addEventListener監聽目標元素事件

 

阻止默認事件

  1. return false
  2. ev.preventDefault()

 

事件委託原理,及優缺點

原理爲事件冒泡機制

優勢

  1. 可大量節省內存佔用,減小事件註冊
  2. 可實現當新增子對象時,無需再對其事件綁定,對於動態內容部分尤其合適

缺點

可能會出現事件誤判,把本不該用觸發事件的被綁上了事件

 

事件循環

Javascriprt爲單線程。單線程的缺點是全部任務需排隊,後一個任務要等前一個任務執行完畢,這樣耗時過久,因而js全部任務分爲兩種:同步任務,異步任務

JS引擎將全部任務按類添加到宏任務、微任務兩個隊列,首先在宏任務隊列中取出第一個任務,執行完畢後,再把微任務隊列中全部任務按序執行完,以後再取宏任務,周而復始,直至兩個隊列的任務都取完,過程就叫事件循環

 

宏任務和微任務

宏任務:setTimeout,setInterval

微任務:Promise,process.nextTick

相關文章
相關標籤/搜索