老生常谈的问题,怎么判断变量是否是一个数组?
- typeof操作符
js中检测数据类型的一种方式,可轻松检测出常用类型,例如,String,Number,Boolean,Function,Undefind,但在对象和数组之间它分不清除。
var a=[];
var b={};
console.log(typeof(a)); //object
console.log(typeof(b));//object
console.log(typeof(null));//object
在js中,Array是由Array构造函数创建的实例,本质上是一个对象,所以用typeof检测数组并不准确。
- instanceof操作符
instanceof操作符用于测试一个对象在其原型链中是否存一个构造函数的prototype属性。Object instanceof constructor
object:要检测的对象
constructor:某个构造函数
var a=[]
console.log(a instanceof Array) //true
instanceof操作符的问题在于,它假定只有一个全局执行环境,如果网页中包含多个框架那实际上就可能存在两个以上的不同的全局环境,从而存在两个以上的Array构造函数,如果从一个框架传入一个数组到另一个框架,那么传入的数组,与第二个框架中创建的数组就有各自不同的构造函数。
- 对象的constructor操属性
对象的constructor属性指向其构造函数
var a=[];
console.log(a.constructor === Array); //true
以上方法在某些条件下课检测数组,但特定情况下会导致结果不准确。
以下是比较常用的方法:
- js中提供了Array.isArray()的方法,用于判断数组。
var a=[]
console.log(a.isArray(a));//true
- 利用对象的toString方法判断数组
每个对象下都有tolocaleString(),toString(),valueOf方法,其中调用数组的toString方法会返回数组中每个值的字符串形式拼接成一个以逗号分隔的字符串。
首先分析Object.prototype.toString的工作过程:
- 获取this对象的[[Class]]属性的值
2.计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串。 - 返回拼接后的字符串
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.[[class]]为一个表明该对象类型的内部属性,其值类型为字符串。
也就是说,用toString方法可以获取对象的[[class]]属性,而[[class]]属性又表明了该对象的类型。
具体操作:
var a=[];
console.log(Object.prototype.toString.call(a)==='[object Array]');//true
call用于改变toString方法中的this指向。
封装成函数为:
var a=[];
var b={};
var c= null;
function isArray(arr){
//因为兼容问题所以判断是否支持Array.isArray函数
if(typeof Array.isArray ==='function'){
return Array.isArray(arr)
}else{
return Object.prototype.toString.call(a)==='[object Array]'
}
}
console.log(isArray(a));//true
console.log(isArray(b));//false
console.log(isArray(c));//false