var obj = { }
var arr = [];
//用constructor判断,arr和obj本身没有constructor属性,但它的原型上有
console.log(arr.constructor === Array)
console.log(obj.constructor === Array);
//用instanceof判断
console.log(arr instanceof Array);
console.log(obj instanceof Array);
//用toString方法
console.log(Object.prototype.toString.call(arr));
console.log(Object.prototype.toString.call(obj));
console.log(Object.prototype.toString.call(obj));
第1种和第2方法在跨域时会失效,当你在多个frame中来回穿梭的时候,由于每个iframe都有一套自己的执行环境,跨frame实例化的对象彼此是不共享原型链的,因此导致上述检测代码失效
下面的代码取自https://www.cnblogs.com/ma-shuai/p/7805264.html
var iframe = document.createElement('iframe'); //创建iframe
document.body.appendChild(iframe); //添加到body中
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // 声明数组[1,2,3]
alert(arr instanceof Array); // false
alert(arr.constructor === Array); // false
出现上述结果的原因是什么呢?其实就是:在当前窗口引入框架,其实就是引入了window对象,当我们在判断iframe框架里的变量时使用arr instanceof Array 或者arr.constructor === Array,要注意这个Array是当前window对象的Array,而不是iframe里的window.Array,所以会返回false
//用Array.isArray方法
Array.isArray()
ECMAScript5将Array.isArray()正式引入JavaScript,目的就是准确地检测一个值是否为数组。IE9+、 Firefox 4+、Safari 5+、Opera 10.5+和 Chrome都实现了这个方法。但是在IE8之前的版本是不支持的。
综合上述方法,自己封装一个函数
var arr = [];
var arr2 = {};
function isArrayFn(value){
if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}
}
alert(isArrayFn(arr));// true
alert(isArrayFn(arr2));// false