少部分人可能首先會想到 typeof
git
var n = 3, b = true, s = 'Hello', x = null, y, obj1 = function() {}, obj2 = {}, obj3 = [], obj4 = new Date(); console.log( typeof n, //number typeof b, //boolean typeof s, //string typeof x, //object typeof y, //undefined typeof obj1, //function typeof obj2, //object typeof obj3, //object typeof obj4 //object );
能夠看出 typeof
是能夠判斷出基本數據類型的,函數也能判斷出來,可是對象、數組、日期都會返回 object,這樣就根本沒法判斷一個對象是否是數組類型。因此 typeof
宣告無能爲力github
var obj1 = {}, obj2 = [1, 2, 3], obj3 = new Date(); console.log(obj1.__proto__ == Array.prototype); //false console.log(obj2.__proto__ == Array.prototype); //true console.log(obj3.__proto__ == Array.prototype); //false
可是 __proto__
是內部屬性,本不該該被訪問到,咱們能夠用 Object.getPrototypeOf(obj)
方法來代替他,雖然這個方法其實內部原理也是他,可是仍是有不一樣的。數組
console.log(Object.getPrototypeOf(obj1) == Array.prototype); //false console.log(Object.getPrototypeOf(obj2) == Array.prototype); //true console.log(Object.getPrototypeOf(obj3) == Array.prototype); //false
obj instanceof Array
判斷 obj
是否是被構造函數 Array
創造出來的函數
console.log(obj1 instanceof Array); //false console.log(obj2 instanceof Array); //true console.log(obj3 instanceof Array); //false
但instanceof
不只判斷直接父類型,而是全部在原型鏈上的類型,都返回 true
,因此若是你建立一個對象可是把他的 __proto__
指向 Array
的原型,而後判斷其類型,也會返回 true
。prototype
obj1.__proto__ = Array.prototype; console.log(obj1 instanceof Array); //true
每一個對象內部,都有一個隱藏的 class
屬性,記錄該對象建立時的數據類型 class
屬性不會隨繼承關係的改變而改變。(就至關於查人的 DNA 了吧,小樣還想假裝。)code
這裏有一個問題:內置類型的原型對象中幾乎都重寫了新的 toString()
,只有最頂層的 toString()
才能輸出對象的 class
屬性值,對象
所以咱們能夠用 call
來使用最牛皮的身份鑑別繼承
console.log( Object.prototype.toString.call(obj1) == /*[object Object]*/ '[object Array]' ); //false console.log( Object.prototype.toString.call(obj2) == /*[object Array]*/ '[object Array]' ); //true console.log( Object.prototype.toString.call(obj3) == /*[object Date]*/ '[object Array]' ); //false
Array.isArray
也能夠彌補 typeof
的不足原型鏈
Array.isArray(obj1); //false Array.isArray(obj2); //true Array.isArray(obj3); //false
更多文章來自個人 github ,求個 star 鼓勵一下吧!get