js因为设计上的某些缺陷,导致在对于Array的判断,也是颇费周折的。

typeof 操作符:

对于Function, String, Number ,Undefined 等几种类型的对象来说,他完全可以胜任,但是为Array时,难免会让人失望:

var arr=new Array("1","2","3","4","5");
alert(typeof(arr));  // Object

instanceof 操作符:

运算符会返回一个 Boolean 值,指出对象是否是特定类的一个实例。

var arrayStr=new Array("1","2","3","4","5");
alert(arrayStr instanceof Array);  //true

虽然此时能够完好的工作,但,事实上在多个frame中穿梭就会产生大问题了。所以

var iframe = document.createElement('iframe');    
document.body.appendChild(iframe);    
xArray = window.frames[window.frames.length-1].Array;       
var arr = new xArray("1","2","3","4","5");//这个写法IE大哥下是不支持的,FF下才有

alert(arr instanceof Array); // false 
alert(arr.constructor === Array); // false

ECMA-262中规范定义了Object.prototype.toString的行为:首先,取得对象的一个内部属性[Class],然后依据这个属性,返回一个类似于”object Array“的字符串作为结果(看过ECMA标准的应该都知道,[]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[Class],然后把类型检测转化为字符串比较,以达到我们的目的。于是利用这点,就有了下面这种方法:

function isArray(obj) {  
  return Object.prototype.toString.call(obj) === '[object Array]';   
}

call改变toString的this引用为待检测的对象,返回此对象的字符串表示,然后对比此字符串是否是’object Array‘,以判断其是否是Array的实例。也许你要问了,为什么不直接o.toString()?嗯,虽然Array继承自Object,也会有toString方法,但是这个方法有可能会被改写而达不到我们的要求,而Object.prototype则是老虎的屁股,很少有人敢去碰它的,所以能一定程度保证其“纯洁性”:)。这也是Array.isArray()方法的兼容旧环境(Polyfill)。 如此很好的解决了跨frame对象构建的问题,经过测试,各大浏览器兼容性也很好,可以放心使用。很多框架,比如jQuery、Base2等等,都计划借鉴此方法以实现某些特殊的,比如数组、正则表达式等对象的类型判定!当然也可以写成如下这样:

function isArray2 (v){
return toString.apply(v) === '[object Array]';
}

要注意的是:toString方法极有可能被重写,所以需要使用的时候,可以直接使用Object.prototype.toString()方法。

Array.isArray()See方法

用来判断某个值是否为数组。如果是,则返回 true,否则返回 false。 // 下面的函数调用都返回 true Array.isArray([]); Array.isArray([1]); Array.isArray(new Array()); // 鲜为人知的事实:其实 Array.prototype 也是一个数组。 Array.isArray(Array.prototype);

// 下面的函数调用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });