JavaScript面試知識點

1、Event-Loop,通常出題說執行順序,有可能問與Node的區別

2、Promise

3、ES6有哪些新特性,Promise/Proxy可能會問

4、this指向,打印

5、變量提高

6、JS判斷變量類型

JavaScript 具備七種內置數據類型,它們分別是:html

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol

類型判斷經常使用的方法面試

  • typeof
  • instanceof
  • Object.prototype.toString
  • constructor

使用 typeof 判斷類型編程

typeof 5 // "number"
typeof 'lucas' // "string"
typeof undefined // "undefined"
typeof true // "boolean"

typeof null // "object"

const foo = () => 1
typeof foo // "function"

const foo = {}
typeof foo // "object"

const foo = []
typeof foo // "object"

const foo = new Date()
typeof foo // "object"

const foo = Symbol("foo") 
typeof foo // "symbol"
複製代碼

總結:使用 typeof 能夠準確判斷出除 null 之外的基本類型,以及 function 類型、symbol 類型;null 會被 typeof 判斷爲 object。瀏覽器

使用 instanceof 判斷類型 使用 a instanceof B 判斷的是:a 是否爲 B 的實例,即 a 的原型鏈上是否存在 B 構造函數。所以若是使用:緩存

function Person(name) {
    this.name = name
}
const p = new Person('lucas')

p instanceof Person
複製代碼

這裏 p 是 Person 構造出來的實例。同時,順着 p 的原型鏈,也能找到 Object 構造函數:安全

p.__proto__.__proto__ === Object.prototype
p instanceof Object
複製代碼

注意:服務器

5 instanceof Number // false
new Number(5) instanceof Number // true
複製代碼

咱們使用如下代碼來模擬 instanceof 原理:網絡

// L 表示左表達式,R 表示右表達式
const instanceofMock = (L, R) => {
    if (typeof L !== 'object') {
        return false
    }
    while (true) { 
        if (L === null) {
            // 已經遍歷到了最頂端
            return false
        }
        if (R.prototype === L.__proto__) {
            return true
        }
        L = L.__proto__
    } 
}

複製代碼

使用 constructor 和 Object.prototype.toString 判斷類型閉包

使用 Object.prototype.toString 判斷類型,咱們稱之爲「萬能方法」,「終極方法」:app

console.log(Object.prototype.toString.call(1)) 
// [object Number]

console.log(Object.prototype.toString.call('lucas')) 
// [object String]

console.log(Object.prototype.toString.call(undefined)) 
// [object Undefined]

console.log(Object.prototype.toString.call(true)) 
// [object Boolean]

console.log(Object.prototype.toString.call({})) 
// [object Object]

console.log(Object.prototype.toString.call([])) 
// [object Array]

console.log(Object.prototype.toString.call(function(){})) 
// [object Function]

console.log(Object.prototype.toString.call(null)) 
// [object Null]

console.log(Object.prototype.toString.call(Symbol('lucas'))) 
// [object Symbol]
複製代碼

使用 constructor 能夠查看目標的構造函數,這也能夠進行類型判斷,但也存在着問題,具體請看:

var foo = 5
foo.constructor
// ƒ Number() { [native code] }

var foo = 'Lucas'
foo.constructor
// ƒ String() { [native code] }

var foo = true
foo.constructor
// ƒ Boolean() { [native code] }

var foo = []
foo.constructor
// ƒ Array() { [native code] }

var foo = {}
foo.constructor
// ƒ Object() { [native code] }

var foo = () => 1
foo.constructor
// ƒ Function() { [native code] }

var foo = new Date()
foo.constructor
// ƒ Date() { [native code] }

var foo = Symbol("foo") 
foo.constructor
// ƒ Symbol() { [native code] }

var foo = undefined
foo.constructor
// VM257:1 Uncaught TypeError: Cannot read property 'constructor' of undefined
    at <anonymous>:1:5

var foo = null
foo.constructor
// VM334:1 Uncaught TypeError: Cannot read property 'constructor' of null
    at <anonymous>:1:5
複製代碼

咱們發現對於 undefined 和 null,若是嘗試讀取其 constructor 屬性,將會進行報錯。而且 constructor 返回的是構造函數自己,通常使用它來判斷類型的狀況並很少見。

7、繼承、閉包

8、深度克隆,函數緩存

參考:juejin.im/post/5abb55…

淺克隆

淺克隆之因此被稱爲淺克隆,是由於對象只會被克隆最外部的一層,至於更深層的對象,則依然是經過引用指向同一塊堆內存.

// 淺克隆函數
function shallowClone(o) {
  const obj = {};
  for ( let i in o) {
    obj[i] = o[i];
  }
  return obj;
}
// 被克隆對象
const oldObj = {
  a: 1,
  b: [ 'e', 'f', 'g' ],
  c: { h: { i: 2 } }
};

const newObj = shallowClone(oldObj);
console.log(newObj.c.h, oldObj.c.h); // { i: 2 } { i: 2 }
console.log(oldObj.c.h === newObj.c.h); // true
複製代碼

9、手撕bind/apply/call等

10、var f = function () {} 和 function f () {}的區別

11、模塊化,AMD/CMD的區別

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

使用模塊化的好處:

  • 解決命名衝突
  • 提供複用性
  • 提升代碼可維護性

模塊化的方式

  • 當即執行函數:在早期,使用當即執行函數實現模塊化是常見的手段,經過函數做用域解決了命名衝突、污染全局做用域的問題
  • AMD 和 CMD
  • CommonJS
  • ES Module

AMD/CMD的區別

不少人說requireJS是異步加載模塊,SeaJS是同步加載模塊,這麼理解其實是不許確的,其實加載模塊都是異步的,只不過AMD依賴前置,js能夠方便知道依賴模塊是誰,當即加載,而CMD就近依賴,須要使用把模塊變爲字符串解析一遍才知道依賴了那些模塊,這也是不少人詬病CMD的一點,犧牲性能來帶來開發的便利性,實際上解析模塊用的時間短到能夠忽略

爲何咱們說兩個的區別是依賴模塊執行時機不一樣,爲何不少人認爲ADM是異步的,CMD是同步的(除了名字的緣由。。。)

一樣都是異步加載模塊,AMD在加載模塊完成後就會執行改模塊,全部模塊都加載執行完後會進入require的回調函數,執行主邏輯,這樣的效果就是依賴模塊的執行順序和書寫順序不必定一致,看網絡速度,哪一個先下載下來,哪一個先執行,可是主邏輯必定在全部依賴加載完成後才執行

CMD加載完某個依賴模塊後並不執行,只是下載而已,在全部依賴模塊加載完成後進入主邏輯,遇到require語句的時候才執行對應的模塊,這樣模塊的執行順序和書寫順序是徹底一致的

這也是不少人說AMD用戶體驗好,由於沒有延遲,依賴模塊提早執行了,CMD性能好,由於只有用戶須要的時候才執行的緣由

一、AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊 二、CMD推崇就近依賴,只有在用到某個模塊的時候再去require

12、Object.create({}) 和 new Object()的區別

十3、對JS的見解

參考:www.cnblogs.com/SanMaoSpace… JavaScript是一種基於對象(Object)和事件驅動(Event Driven)並具備相對安全性的客戶端腳本語言。它最初由網景公司(Netscape)的Brendan Eich設計,是一種動態、弱類型、基於原型的語言,內置支持類。

特色

  • 一種解釋性執行的腳本語言。 JavaScript的語法基本結構形式與C、C++、Java十分相似。但在使用前,不像這些語言須要先編譯,而是在程序運行過程當中被逐行地解釋

  • 一種基於對象的腳本語言。

  • 一種簡單弱類型腳本語言。

  • 一種相對安全腳本語言。

  • 一種事件驅動腳本語言。

  • 一種跨平臺性腳本語言。

優勢

  • JavaScript可使多種任務僅在用戶端就能夠完成,而不須要網絡和服務器的參與
  • JavaScript能夠方便地操縱各類頁面中的對象,用戶可使用JavaScript來控制頁面中各個元素的外觀、狀態甚至運行方式,JavaScript能夠根據用戶的須要「定製」瀏覽器,從而使網頁更加友好。

缺點

  • 各瀏覽器廠商對JavaScript支持程度不一樣。
  • 「Web安全性」對JavaScript一些功能犧牲。

十4、JS 異步編程及常考面試題

涉及面試題:什麼是回調函數?回調函數有什麼缺點?如何解決回調地獄問題?

相關文章
相關標籤/搜索