¿Cuál es el mejor método estándar de facto entre navegadores para determinar si una variable en JavaScript es una matriz o no?
Al buscar en la web, hay una serie de sugerencias diferentes, algunas buenas y algunas no válidas.
Por ejemplo, el siguiente es un enfoque básico:
function isArray(obj) {
return (obj && obj.length);
}
Sin embargo, tenga en cuenta lo que sucede si la matriz está vacía, o si obj en realidad no es una matriz, pero implementa una propiedad de longitud, etc.
Entonces, ¿qué implementación es la mejor en términos de funcionar realmente, ser entre navegadores y seguir funcionando de manera eficiente?
javascript
arrays
stpe
fuente
fuente
Respuestas:
La verificación de tipos de objetos en JS se realiza mediante
instanceof
, es decirEsto no funcionará si el objeto pasa a través de los límites del marco, ya que cada marco tiene su propio
Array
objeto. Puede solucionar este problema comprobando la propiedad [[Class]] interna del objeto. Para obtenerlo, utiliceObject.prototype.toString()
(ECMA-262 garantiza que funciona):Ambos métodos solo funcionarán para matrices reales y no para objetos similares a matrices como el
arguments
objeto o las listas de nodos. Como todos los objetos tipo matriz deben tener unalength
propiedad numérica , verificaría estos como este:Tenga en cuenta que las cadenas pasarán esta verificación, lo que podría generar problemas ya que IE no permite el acceso a los caracteres de una cadena por índice. Por lo tanto, es posible que desee cambiar
typeof obj !== 'undefined'
atypeof obj === 'object'
para excluir primitivas y objetos host con tipos distintos de todos'object'
juntos. Esto todavía permitirá que pasen los objetos de cadena, que deberían excluirse manualmente.En la mayoría de los casos, lo que realmente desea saber es si puede iterar sobre el objeto mediante índices numéricos. Por lo tanto, podría ser una buena idea verificar si el objeto tiene una propiedad nombrada
0
en su lugar, lo que se puede hacer a través de una de estas verificaciones:La conversión a objeto es necesaria para que funcione correctamente para primitivas de tipo arreglo (es decir, cadenas).
Aquí está el código para comprobaciones sólidas para matrices JS:
y objetos similares a matrices iterables (es decir, no vacíos):
fuente
hasOwnProperty
método, así que simplemente anteponga suinstanceof
conobj.hasOwnProperty &&
; Además, ¿sigue siendo un problema con IE7? mis pruebas simples a través del administrador de tareas sugieren que la memoria se recuperó después de minimizar el navegador ...La llegada de ECMAScript 5th Edition nos brinda el método de prueba más seguro si una variable es una matriz, Array.isArray () :
Si bien la respuesta aceptada aquí funcionará en marcos y ventanas para la mayoría de los navegadores, no es así para Internet Explorer 7 y versiones anteriores , ya que
Object.prototype.toString
se devolverá la llamada en una matriz desde una ventana diferente[object Object]
, no[object Array]
. IE 9 parece haber regresado a este comportamiento también (consulte la corrección actualizada a continuación).Si desea una solución que funcione en todos los navegadores, puede usar:
No es del todo irrompible, pero solo alguien que se esfuerce por romperlo lo romperá. Resuelve los problemas en IE7 y versiones inferiores e IE9. El error aún existe en IE 10 PP2 , pero podría corregirse antes del lanzamiento.
PD, si no está seguro acerca de la solución, le recomiendo que la pruebe con el contenido de su corazón y / o lea la publicación del blog. Hay otras posibles soluciones allí si no se siente cómodo con la compilación condicional.
fuente
isArray
no devuelve verdadero de matrices creadas en otros modos de documento? Tendré que investigar esto cuando tenga tiempo, pero creo que lo mejor que se puede hacer es enviar un error en Connect para que se pueda solucionar en IE 10.Crockford tiene dos respuestas en la página 106 de "Las partes buenas". El primero verifica el constructor, pero dará falsos negativos en diferentes marcos o ventanas. Aquí está el segundo:
Crockford señala que esta versión identificará la
arguments
matriz como una matriz, aunque no tenga ninguno de los métodos de matriz.Su interesante discusión sobre el problema comienza en la página 105.
Hay más discusión interesante (post-Good Parts) aquí que incluye esta propuesta:
Toda la discusión me hace no querer saber si algo es una matriz o no.
fuente
jQuery implementa una función isArray, que sugiere que la mejor manera de hacerlo es
(fragmento tomado de jQuery v1.3.2 - ligeramente ajustado para que tenga sentido fuera de contexto)
fuente
Object.prototype.toString()
- es menos probable que se rompaRobando al gurú John Resig y jquery:
fuente
typeof
están estandarizados?¿Qué vas a hacer con el valor una vez que decidas que es una matriz?
Por ejemplo, si tiene la intención de enumerar los valores contenidos si se ve como una matriz O si es un objeto que se usa como una tabla hash, entonces el siguiente código obtiene lo que desea (este código se detiene cuando la función de cierre devuelve cualquier otra cosa que "indefinido". Tenga en cuenta que NO itera sobre contenedores COM o enumeraciones; eso se deja como un ejercicio para el lector):
(Nota: pruebas "o! = Null" tanto para nulo como para indefinido)
Ejemplos de uso:
fuente
for..in
es malo [tm])for..in
itera sobre propiedades enumerables de objetos; no debería usarlo con matrices porque: (1) es lento; (2) no se garantiza que mantenga el orden; (3) incluirá cualquier propiedad definida por el usuario establecida en el objeto o cualquiera de sus prototipos, ya que ES3 no incluye ninguna forma de establecer el atributo DontEnum; puede haber otros problemas que se me han olvidadoSi está haciendo esto en CouchDB (SpiderMonkey), use
Array.isArray(array)
como
array.constructor === Array
oarray instanceof Array
no funcionan. El usoarray.toString() === "[object Array]"
funciona, pero parece bastante dudoso en comparación.fuente
Si desea varios navegadores, desea jQuery.isArray .
fuente
En w3school hay un ejemplo que debería ser bastante estándar.
Para verificar si una variable es una matriz, usan algo similar a esto
probado en Chrome, Firefox, Safari, ie7
fuente
constructor
para la verificación de tipos es demasiado frágil; use una de las alternativas sugeridas en su lugarconstructor
es una propiedad DontEnum regular del objeto prototipo; esto puede no ser un problema para los tipos integrados siempre que nadie haga nada estúpido, pero para los tipos definidos por el usuario puede serlo fácilmente; mi consejo: siempre useinstanceof
, que verifica la cadena de prototipos y no se basa en propiedades que se pueden sobrescribir arbitrariamenteUna de las versiones mejor investigadas y discutidas de esta función se puede encontrar en el sitio PHPJS . Puede vincular a paquetes o puede ir directamente a la función . Recomiendo encarecidamente el sitio para obtener equivalentes bien construidos de funciones PHP en JavaScript.
fuente
No hay suficientes referencias iguales de constructores. En algún momento tienen diferentes referencias de constructor. Entonces uso representaciones de cadenas de ellos.
fuente
{constructor:{toString:function(){ return "function Array() { [native code] }"; }}}
Reemplazar
Array.isArray(obj)
porobj.constructor==Array
muestras:
Array('44','55').constructor==Array
devuelve verdadero (IE8 / Chrome)'55'.constructor==Array
devolver falso (IE8 / Chrome)fuente