JavaScript 具備七種內置數據類型,它們分別是:html
類型判斷經常使用的方法面試
使用 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 返回的是構造函數自己,通常使用它來判斷類型的狀況並很少見。
淺克隆之因此被稱爲淺克隆,是由於對象只會被克隆最外部的一層,至於更深層的對象,則依然是經過引用指向同一塊堆內存.
// 淺克隆函數
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
複製代碼
涉及面試題:爲何要使用模塊化?都有哪幾種方式能夠實現模塊化,各有什麼特色?
使用模塊化的好處:
模塊化的方式
AMD/CMD的區別
不少人說requireJS是異步加載模塊,SeaJS是同步加載模塊,這麼理解其實是不許確的,其實加載模塊都是異步的,只不過AMD依賴前置,js能夠方便知道依賴模塊是誰,當即加載,而CMD就近依賴,須要使用把模塊變爲字符串解析一遍才知道依賴了那些模塊,這也是不少人詬病CMD的一點,犧牲性能來帶來開發的便利性,實際上解析模塊用的時間短到能夠忽略
爲何咱們說兩個的區別是依賴模塊執行時機不一樣,爲何不少人認爲ADM是異步的,CMD是同步的(除了名字的緣由。。。)
一樣都是異步加載模塊,AMD在加載模塊完成後就會執行改模塊,全部模塊都加載執行完後會進入require的回調函數,執行主邏輯,這樣的效果就是依賴模塊的執行順序和書寫順序不必定一致,看網絡速度,哪一個先下載下來,哪一個先執行,可是主邏輯必定在全部依賴加載完成後才執行
CMD加載完某個依賴模塊後並不執行,只是下載而已,在全部依賴模塊加載完成後進入主邏輯,遇到require語句的時候才執行對應的模塊,這樣模塊的執行順序和書寫順序是徹底一致的
這也是不少人說AMD用戶體驗好,由於沒有延遲,依賴模塊提早執行了,CMD性能好,由於只有用戶須要的時候才執行的緣由
一、AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊 二、CMD推崇就近依賴,只有在用到某個模塊的時候再去require
參考:www.cnblogs.com/SanMaoSpace… JavaScript是一種基於對象(Object)和事件驅動(Event Driven)並具備相對安全性的客戶端腳本語言。它最初由網景公司(Netscape)的Brendan Eich設計,是一種動態、弱類型、基於原型的語言,內置支持類。
特色
一種解釋性執行的腳本語言。 JavaScript的語法基本結構形式與C、C++、Java十分相似。但在使用前,不像這些語言須要先編譯,而是在程序運行過程當中被逐行地解釋
一種基於對象的腳本語言。
一種簡單弱類型腳本語言。
一種相對安全腳本語言。
一種事件驅動腳本語言。
一種跨平臺性腳本語言。
優勢
缺點
涉及面試題:什麼是回調函數?回調函數有什麼缺點?如何解決回調地獄問題?