怎麼去區分一個變量是一個數組仍是一個對象呢?html
看到這個題目,可能首先就會typeof,typeof是最基本的數據類型判斷方式,在不考慮es6的狀況下,typeof可能的返回值有下面這些:es6
"undefined" //若是這個值未定義 "boolean" //若是這個值是布爾值 "string" //若是這個值是字符串 "number" //若是這個值是數值 "object" //若是這個值是對象或null "function" //若是這個值是函數
你能夠發現typeof可能的返回值並無array,也就是說typeof並不能幫你檢測出一個數組。事實上,不管引用的是什麼類型的對象,它都返回 "object"。若是使用typeof去檢測一個數組,返回的也將會是"object"。面試
instanceof運算符用來判斷一個構造函數的prototype屬性所指向的對象是否存在另一個要檢測對象的原型鏈上。
使用它的方式是:obj instanceof Object
這句話檢測Object.prototype是否存在於參數obj的原型鏈上。
其實它已經可以很好區別開對象和數組了,看下面的例子:數組
var arr = [1, 2]; var obj = { name: 'name' } console.log(arr instanceof Array); //true console.log(obj instanceof Array); //false
但它也有一丟丟問題,既然它會去在整個原型鏈上去找,而ECMAScript中Object是全部對象的基礎,那麼,若是使用instanceof去判斷一個數組是否是對象的時候,會不會也返回true呢?函數
var arr = [1,2]; console.log(arr instanceof Object); //true console.log(arr instanceof Array); //true
答案是確定的,因此感受這種判斷方式也有小瑕疵。prototype
constructor 屬性返回對建立此對象的函數的引用。因此大多數時候它返回的都是一個對象的構造函數。
看例子:設計
var arr = [1,2]; console.log(arr.constructor === Array); //true console.log(arr.constructor === Object); //false
但既然想要挑刺,咱們就想一想這種方式有什麼問題。constructor屬性實際上是存在一個對象的原型中的,因此,若是他的原型被改變了,這種方法還會有用麼?
仍是例子:code
var arr = [1,2]; arr.__proto__ = {} console.log(arr.constructor === Array); //false console.log(arr.constructor === Object); //true
哈哈,不錯所料的,咱們改變了arr的__proto__屬性爲一個對象以後,constructor也給咱們作出了錯誤的判斷,因此,這種方法也有被玩壞的可能。htm
最後就是經過toString()方法,數組原型和對象原型定義的toString()方法不一樣。對象
參考:http://www.cnblogs.com/ziyunf...
接着看例子:
var arr = [1, 2]; var obj = { name: "name", } console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true console.log(Object.prototype.toString.call(boj) === '[object Array]'); //false
看到這道題仍是我第一次面試的時候,比較萌新,抱的態度也是去積累點經驗,準備的不充分。被問到這個題的時候,首先個人第一反應是找一個數組中有的,對象中沒有的屬性去判斷,好比length,但說出來我就後悔了,對象中沒有length這個屬性難道咱們不能給它賦一個麼,而那時我還知道若是用typeof的話,他倆都會返回object。想到了構造函數可能不同,但說怎麼判斷就有點想不出詞了,就持續懵逼中...
這篇內容參考了《JavaScript高級程序設計》和一篇文章:http://www.cnblogs.com/Walker...