JS的經典問題之一就是「檢測一個對象是否是數組」,本文總結了3種檢測方法。正則表達式
var arr = []; if (arr instanceof Array) { // do something }
存在問題instanceof
操做符假設只有一個全局執行環境。若是網頁中包含多個框架,那實際上存在兩個以上的不一樣全局執行環境,從而存在兩個以上不一樣版本的Array構造函數。若是從一個框架向另外一個框架傳入數組,那麼傳入的數組與第二框架中原生的數組分別具備各自不一樣的構造函數。從而將傳入的數組誤判爲非數組。數組
若是隻有一個全局執行環境,能夠用 instanceof
檢測數組。瀏覽器
var arr = []; if (Array.isArray(arr)) { // do something }
這個方法克服了instanceof
的問題,能夠肯定某個變量是否是數組,而無論它是在哪一個全局執行環境中建立的。
可是支持Array.isArray()
方法的瀏覽器有IE9+、Firefox4+、Safari5+、Opera10.5+和Chrome。對於不支持這個方法的瀏覽器怎麼辦呢?第三種——萬能方法。框架
function isArray(arr) { return Object.prototype.toString.call(arr) == '[object Array]'; } var arr = []; isArray(arr);
原理
在任何值上調用Object原生的toString()
方法,都會返回一個[object NativeConstructorName]
格式的字符串。每一個類在內部都有一個[ [Class] ]屬性,這個屬性就指定了上述字符串中的構造函數名NativeConstructorName
。如:函數
var arr = []; console.log(Object.pototype.toString.call(arr)); // "[object Array]"
這種思路也可用於檢測某個值是否是原生函數或正則表達式。prototype
// Array Object.prototype.toString.call(value); // "[object Array]" // Function Object.prototype.toString.call(value); // "[object Function]" // RegExp Object.prototype.toString.call(value); // "[object RegExp]" // Date Object.prototype.toString.call(value); // "[object Date]"
Object的toString()方法不能檢測非原生的構造函數的構造函數名,所以,開發人員定義的任何構造函數都將返回[object Object]。code