最近写代码时候遇到了判断变量是对象还是数组,然后就去搜了一下,记录之后总结一下方法:
首先是通过length去判断,一般情况下对象没有length属性值,其值为undefiend,而数组的length值为number类型 ,但是这种方法非常不实用,一但对象的属性存在length之后(比如类数组),其值也为number,则该方法失效。所以不建议使用。
下面是我找到的几种方法,个人推荐使用第四种。
var arr = ['a','b','c','d']
var obj = {
a: '11',
b: '22',
c: '33'
}
1. typeOf
我们可以使用typeOf来判断变量,判断字符串得到string,判断数字和NaN得到number,判断函数得到function。但是判断数组、对象和null都是只会得到Object,并不能准确的判断变量,这就是typeOf的局限性。
2. instanceof
判断一个数组是否由构造函数(Array)创建出来的
console.log(arr instanceof Array); //true
console.log(arr instanceof Object); //true
console.log(obj instanceof Array); //false
console.log(obj instanceof Object); //true
3. constructor
console.log(arr.constructor === Array); //true
console.log(arr.constructor === Object); //false
console.log(obj.constructor === Object); //true
instanceof 和constructor 判断的变量,必须在当前页面声明的,比如,一个页面(父页面)有一个iframe,iframe中引用了一个页面(子页面),在子页面中声明了一个a,并将其赋值给父页面的一个变量arr,这时判断该变量, arr.constructor===Array 或arr instanceof Array都会返回false
原因:
每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;
4. Object.prototype.toString.call()
Object.prototype.toString.call()方法可以精准判断变量类型,它返回[object constructorName]的字符串格式,这里的constructorName就是call参数的函数名
var res = Object.prototype.toString.call(arr);
console.log(res); //[object Array]
var res2 = Object.prototype.toString.call(obj);
console.log(res2); //[object Object]
5. Array.isArray()
Array.isArray(arr); // true
Array.isArray(obj); //false