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