如何检测一个variables是否是一个数组

什么是最好的事实上的标准的跨浏览器方法来确定JavaScript中的variables是否是一个数组?

在网上search有一些不同的build议,一些很好,很多是无效的。

例如,以下是一个基本的方法:

function isArray(obj) { return (obj && obj.length); } 

但是,请注意,如果数组为空,或者obj实际上不是数组,而是实现了长度属性等等会发生什么情况。

那么哪个实现在实际工作中是最好的,跨浏览器并且仍然有效地执行?

在JS中检查对象的types是通过instanceof完成的

 obj instanceof Array 

如果对象跨越边框传递,每个框架都有自己的Array对象,则这将不起作用。 你可以通过检查对象的内部[[Class]]属性来解决这个问题。 为了得到它,使用Object.prototype.toString() (这是保证由ECMA-262工作):

 Object.prototype.toString.call(obj) === '[object Array]' 

这两种方法只适用于实际的数组,而不是类似于arguments对象或节点列表的类似数组的对象。 由于所有类似数组的对象都必须有一个数字length属性,所以我会检查它们是这样的:

 typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number' 

请注意,string将通过此检查,这可能会导致问题,因为IE不允许通过索引访问string的字符。 因此,您可能需要将typeof obj !== 'undefined'更改为typeof obj === 'object'以排除与'object'不同的types的基元和宿主对象。 这仍然会让string对象通过,这将不得不手动排除。

在大多数情况下,你真正想知道的是你是否可以通过数字索引迭代对象。 因此,检查对象是否具有名为0的属性可能是一个好主意,可以通过以下其中一种检查来完成:

 typeof obj[0] !== 'undefined' // false negative for `obj[0] = undefined` obj.hasOwnProperty('0') // exclude array-likes with inherited entries '0' in Object(obj) // include array-likes with inherited entries 

对象的强制转换对于类似数组的基元(即string)正确工作是必要的。

下面是对JS数组进行健壮检查的代码:

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

和可迭代的(即非空的)类似数组的对象:

 function isNonEmptyArrayLike(obj) { try { // don't bother with `typeof` - just access `length` and `catch` return obj.length > 0 && '0' in Object(obj); } catch(e) { return false; } } 

ECMAScript 5th Edition的到来为我们提供了一个最可靠的testing方法,如果一个variables是一个数组Array.isArray()

 Array.isArray([]); // true 

虽然这里接受的答案将在大多数浏览器的跨框架和窗口上工作, 但它不适用于Internet Explorer 7及更低版本 ,因为从另一个窗口调用的数组的Object.prototype.toString将返回[object Object] ,而不是[object Array] 。 IE 9似乎已经退化到这种行为(见下面更新的修复)。

如果你对这个博客文章感兴趣的话,我不会深入到这个解决scheme的所有细节部分。 但是,如果您想要一个适用于所有浏览器的解决scheme,则可以使用:

 (function () { var toString = Object.prototype.toString, strArray = Array.toString(), jscript = /*@cc_on @_jscript_version @*/ +0; // jscript will be 0 for browsers other than IE if (!jscript) { Array.isArray = Array.isArray || function (obj) { return toString.call(obj) == "[object Array]"; } } else { Array.isArray = function (obj) { return "constructor" in obj && String(obj.constructor) == strArray; } } })(); 

这不是完全牢不可破的,但只有被试图打破它的人才会被打破。 它解决了IE7和IE9以下的问题。 该错误仍然存​​在于IE 10 PP2中 ,但在发布之前可能会被修复。

PS,如果你不确定解决scheme,那么我build议你testing一下你的内容和/或阅读博客文章。 如果使用条件编译不舒服,还有其他可能的解决scheme。

Crockford在“The Good Parts”的第106页有两个答案。 第一个检查构造函数,但会给不同的框架或窗口带来错误的否定。 这是第二个:

 if (my_value && typeof my_value === 'object' && typeof my_value.length === 'number' && !(my_value.propertyIsEnumerable('length')) { // my_value is truly an array! } 

克罗克福德指出,这个版本将识别arguments数组作为数组,即使它没有任何数组方法。

他对这个问题的有趣讨论从第105页开始。

这里还有一个有趣的讨论(好的部分),包括这个build议:

 var isArray = function (o) { return (o instanceof Array) || (Object.prototype.toString.apply(o) === '[object Array]'); }; 

所有的讨论使我从不想知道某物是否是一个数组。

jQuery实现了一个isArray函数,这表明最好的方法是

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

(取自jQuery v1.3.2的片段 – 稍微调整一下,使之脱离上下文)

从上师John Resig和jquery窃取:

 function isArray(array) { if ( toString.call(array) === "[object Array]") { return true; } else if ( typeof array.length === "number" ) { return true; } return false; } 

一旦你决定它是一个数组,你将如何处理这个值?

例如,如果打算枚举包含的值,如果它看起来像一个数组,或者如果它是一个对象被用作一个哈希表,然后下面的代码得到你想要的(当闭包函数返回其他东西而不是“undefined”。注意,它不会遍历COM容器或枚举;这只是读者的练习):

 function iteratei( o, closure ) { if( o != null && o.hasOwnProperty ) { for( var ix in seq ) { var ret = closure.call( this, ix, o[ix] ); if( undefined !== ret ) return ret; } } return undefined; } 

(注意:“o!= null”testingnull和undefined)

使用示例:

 // Find first element who's value equals "what" in an array var b = iteratei( ["who", "what", "when" "where"], function( ix, v ) { return v == "what" ? true : undefined; }); // Iterate over only this objects' properties, not the prototypes' function iterateiOwnProperties( o, closure ) { return iteratei( o, function(ix,v) { if( o.hasOwnProperty(ix) ) { return closure.call( this, ix, o[ix] ); } }) } 

如果你想跨浏览器,你想要jQuery.isArray 。

在w3school有一个例子,应该是相当标准的。

要检查一个variables是否是一个数组,他们使用类似的东西

 function arrayCheck(obj) { return obj && (obj.constructor==Array); } 

在Chrome,Firefox,Safari,ie7上进行testing

在PHPJS网站上可以find这个函数最好的研究和讨论版本之一。 你可以链接到包,或者你可以直接去函数 。 我强烈build议在JavaScript中使用构造良好的PHP函数的网站。

没有足够的引用等​​于构造函数。 有时他们有不同的构造函数的引用。 所以我使用它们的string表示。

 function isArray(o) { return o.constructor.toString() === [].constructor.toString(); } 

obj.constructor==ArrayreplaceArray.isArray(obj)

样品:

Array('44','55').constructor==Array返回true(IE8 / Chrome)

'55'.constructor==Array返回false(IE8 / Chrome)