¿Cómo se comprueba si una variable es una matriz en JavaScript? [duplicar]
Frecuentes
Visto 1,013 equipos
1844
Me gustaría comprobar si una variable es una matriz o un valor único en JavaScript.
He encontrado una posible solución ...
if (variable.constructor == Array)...
¿Es esta la mejor manera de hacerlo?
23 Respuestas
1741
Hay varias formas de comprobar si una variable es una matriz o no. La mejor solución es la que ha elegido.
variable.constructor === Array
Este es el método más rápido en Chrome y muy probablemente en todos los demás navegadores. Todas las matrices son objetos, por lo que comprobar la propiedad del constructor es un proceso rápido para los motores JavaScript.
Si tiene problemas para averiguar si la propiedad de un objeto es una matriz, primero debe verificar si la propiedad está allí.
variable.prop && variable.prop.constructor === Array
Algunas otras formas son:
Array.isArray(variable)
Actualización 23 de mayo de 2019 usando Chrome 75, un saludo a @AnduAndrici por hacerme revisar esto con su pregunta
Este último es, en mi opinión, el más feo, y es uno de los el más lento lo más rápido. Corriendo aproximadamente 1/5 de la velocidad como primer ejemplo. Este tipo es aproximadamente un 2-5% más lento, pero es bastante difícil de decir. ¡Sólido para usar! Muy impresionado por el resultado. Array.prototype, es en realidad una matriz. Puedes leer más sobre esto aquí https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
variable instanceof Array
Este método corre sobre 1/3 de la velocidad como primer ejemplo. Sigue siendo bastante sólido, se ve más limpio, si lo que te gusta es el código bonito y no tanto el rendimiento. Tenga en cuenta que la comprobación de números no funciona como variable instanceof Number
siempre vuelve false
. Actualizar: instanceof
ahora va a 2/3 de la velocidad!
Así que otra actualización más
Object.prototype.toString.call(variable) === '[object Array]';
Este tipo es el más lento para intentar buscar una matriz. Sin embargo, esta es una ventanilla única para cualquier tipo que esté buscando. Sin embargo, dado que está buscando una matriz, simplemente use el método más rápido anterior.
Además, realicé una prueba: http://jsperf.com/instanceof-array-vs-array-isarray/35 Así que diviértete y compruébalo.
Nota: @EscapeNetscape ha creado otra prueba ya que jsperf.com está inactivo. http://jsben.ch/#/QgYAV Quería asegurarme de que el enlace original permanezca siempre que jsperf vuelva a estar en línea.
contestado el 23 de mayo de 19 a las 18:05
Para extender la respuesta dada otra prueba jsperf aquí utilizando pruebas de funciones (.push && .pop), que es la forma más rápida y compatible con todos los navegadores (incluso los antiguos). El problema es que tal vez un objeto tiene propiedades 'push' y 'pop' sin ser una matriz. También tenga en cuenta que cuando se prueba si una matriz con un objeto creado (o pasado) desde otro marco, la mayoría de las pruebas fallarán (ya que el Formación en una ventana dada es diferente a Formación en la ventana del marco). También hay un problema si una matriz se construye a través de una nueva matriz o literalmente como [..] - nikos m.
Tenga en cuenta que si no está seguro de si la variable está definida o si podría ser nula, asegúrese de hacer esas comprobaciones primero, ya que esos son los valores / objetos comunes que no tienen un constructor. - Michael Scott Cuthbert
variable.constructor es más rápido solo para verificar matrices reales. Al verificar objetos aleatorios (y en el mundo real este será el caso, ya que esta es la razón por la que usa esta función) es más rápido usar instanceof. jsperf.com/check-if-variable-is-array - dinu sorin
NOTA: 'variable.constructor === Array' arrojará EXCEPCIÓN si la variable es nula pero la 'instancia variable de Array' no. - GorvGoyl
A partir de Chrome 59, isArray () parece ser significativamente más rápido, tanto que no veo ninguna razón para no usar isArray () en todas las situaciones. - hedley smith
1063
También puedes usar:
if (value instanceof Array) {
alert('value is Array!');
} else {
alert('Not an array');
}
Esta me parece una solución bastante elegante, pero para cada uno lo suyo.
Edit:
A partir de ES5, ahora también hay:
Array.isArray(value);
Pero esto se romperá en los navegadores más antiguos, a menos que esté usando polyfills (básicamente ... IE8 o similar).
Respondido 04 ago 17, 21:08
Sugiero que insista en seguir con este operador "instancia de" si no está trabajando con varios marcos. Ésta es la forma correcta de comprobar el tipo de objeto. - pork
El único caso en el que esto fallaría es si estuviera intentando probar una matriz u objeto desde Array instanceof Object == true
. - Pierre
Si está utilizando jQuery para pasar elementos con find ('código') o algo similar, querrá verificar la variable con variable instanceof Object
ya que no es una instancia de Array. - pliegue
@BrettBender Si todavía está activo, ¿podría actualizar su respuesta para reflejar que a partir de ES5 tenemos Array.isArray? - Nobbynob Littlun
@AndrewK ver La respuesta de Fela Winkelmolen, que tiene el método Array.isArray. En cuanto a esta respuesta, probablemente no sea una buena idea transformar una respuesta en una respuesta diferente mediante la edición. - muffin
79
Existen múltiples soluciones con todas sus peculiaridades. En esta página ofrece una buena descripción general. Una posible solución es:
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
Respondido 11 Oct 15, 20:10
Si lee con atención, dice que este método es necesario cuando se trabaja con documentos de varios marcos, lo cual no se recomienda. Este método puede realizar fácilmente un pequeño cambio en la función "toString". - pork
Por lo tanto, el enlace se proporciona para que Brett pueda verificarlos y ver en qué caso su función tiene que funcionar: Pedro Smith
Vea mi respuesta a continuación. Recomiendo el estilo de Peter Smit. - Brian
Este metodo es recomendado por Mozilla. - Hank
77
Noté que alguien mencionó jQuery, pero no sabía que había un isArray()
función. Resulta que se agregó en la versión 1.3.
jQuery lo implementa como sugiere Peter:
isArray: function( obj ) {
return toString.call(obj) === "[object Array]";
},
Habiendo puesto mucha fe en jQuery (especialmente en sus técnicas para la compatibilidad entre navegadores), actualizaré a la versión 1.3 y usaré su función (siempre que la actualización no cause demasiados problemas) o usaré este método sugerido directamente en mi código.
Muchas gracias por las sugerencias.
respondido 15 nov., 12:17
Ver este artículo para una buena discusión sobre el tema. La conclusión es utilizar esta solución. - nick g
Esto me da el error SCRIPT65535 en IE10. - polm23
73
En los navegadores modernos (y algunos navegadores heredados), puede hacer
Array.isArray(obj)
(Apoyado por Chrome 5, Firefox 4.0, IE 9, Opera 10.5 y Safari 5)
Si necesita admitir versiones anteriores de IE, puede usar es5-calce para polyfill Array.isArray; o agrega lo siguiente
# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
};
Si usa jQuery puede usar jQuery.isArray(obj)
or $.isArray(obj)
. Si usa guión bajo, puede usar _.isArray(obj)
Si no necesita detectar matrices creadas en diferentes marcos, también puede usar instanceof
obj instanceof Array
Nota: el arguments
La palabra clave que se puede usar para acceder al argumento de una función no es una matriz, aunque (generalmente) se comporta como una:
var func = function() {
console.log(arguments) // [1, 2, 3]
console.log(arguments.length) // 3
console.log(Array.isArray(arguments)) // false !!!
console.log(arguments.slice) // undefined (Array.prototype methods not available)
console.log([3,4,5].slice) // function slice() { [native code] }
}
func(1, 2, 3)
Respondido el 31 de enero de 19 a las 12:01
Este es probablemente el mejor enfoque más moderno. Lo he visto junto con el polyfill en MDN, por lo que eso significa que Mozilla confía en él. desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Juan
No te estas perdiendo prototype
¿allí? Parece que debería ser Object.prototype.toString.call
. - Brock
55
Esta es una pregunta antigua, pero al tener el mismo problema, encontré una solución muy elegante que quiero compartir.
Agregar un prototipo a Array lo hace muy simple
Array.prototype.isArray = true;
Ahora, una vez, si tiene un objeto que desea probar para ver si es una matriz, todo lo que necesita es verificar la nueva propiedad
var box = doSomething();
if (box.isArray) {
// do something
}
isArray solo está disponible si es una matriz
Respondido 24 Oct 11, 22:10
@Vitimtk Un prototipo actúa como un respaldo para el objeto real, por lo que debería funcionar incluso si la matriz en cuestión ya existía. No funcionará antes de que se procese la línea fuente, por supuesto. - marcus bruckner
Asumiendo que nadie lo hace Object.prototype.isArray = true;
! :( - ErikE
Tenga en cuenta que en ES5 Array.isArray
es un método (p. ej., Array.isArray([1,2,3]) === true
) así que @ErikE no estaba siendo un troll. Evitaría seguir esta respuesta, ya que romperá el código en algunos navegadores modernos. - JaredMcAteer
@Ibu y tu puedes hacer {}.isArray === true
con mi "solución", que era el punto ... - ErikE
Modificar el prototipo de tipos de datos es una mala práctica en mi opinión - BentOnCodificación
47
Vía Crockford:
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (value instanceof Array) {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
La principal falla que menciona Crockford es la incapacidad de determinar correctamente las matrices que se crearon en un contexto diferente, por ejemplo, window
. Esa página tiene una versión mucho más sofisticada si esta es insuficiente.
Respondido 20 Abr '09, 10:04
29
Si solo está tratando con EcmaScript 5 y superior, puede usar el Array.isArray
función
e.g.,
Array.isArray([]) // true
Array.isArray("foo") // false
Array.isArray({}) // false
Respondido el 31 de enero de 19 a las 17:01
28
Personalmente, me gusta la sugerencia de Peter: https://stackoverflow.com/a/767499/414784 (para ECMAScript 3. Para ECMAScript 5, utilice Array.isArray()
)
Los comentarios en la publicación indican, sin embargo, que si toString()
cambia en absoluto, esa forma de verificar una matriz fallará. Si realmente quiere ser específico y asegúrese toString()
no se ha cambiado y no hay problemas con el atributo de clase de objetos ([object Array]
es el atributo de clase de un objeto que es una matriz), entonces recomiendo hacer algo como esto:
//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
// make sure an array has a class attribute of [object Array]
var check_class = Object.prototype.toString.call([]);
if(check_class === '[object Array]')
{
// test passed, now check
return Object.prototype.toString.call(o) === '[object Array]';
}
else
{
// may want to change return value to something more desirable
return -1;
}
}
Tenga en cuenta que en JavaScript The Definitive Guide 6th edition, 7.10, dice Array.isArray()
se implementa usando Object.prototype.toString.call()
en ECMAScript 5. También tenga en cuenta que si va a preocuparse por toString()
Si cambia la implementación, también debe preocuparse por cualquier otro método integrado que cambie. Por que usar push()
? ¡Alguien puede cambiarlo! Tal enfoque es una tontería. El cheque anterior es una solución ofrecida a aquellos preocupados por toString()
cambiando, pero creo que el cheque es innecesario.
contestado el 23 de mayo de 17 a las 13:05
Buena decisión sobre el estándar ECMAScript 5. Seguro que no puede garantizar que el navegador lo admita, pero esta debería ser la primera forma de ingresar un nuevo código. - estilo
Comenzaré diciendo que esto es un poco exagerado. Sin embargo, ¿una prueba como esta sería más robusta ?: return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
- otorgar lindsay
20
Cuando publiqué esta pregunta, la versión de JQuery que estaba usando no incluía un isArray
función. Si lo hubiera hecho, probablemente lo habría usado confiando en que la implementación es la mejor forma independiente del navegador para realizar esta verificación de tipo en particular.
Dado que JQuery ahora ofrece esta función, siempre la usaría ...
$.isArray(obj);
(a partir de la versión 1.6.2) Todavía se implementa mediante comparaciones en cadenas en el formulario
toString.call(obj) === "[object Array]"
Respondido 08 ago 11, 15:08
17
Pensé que agregaría otra opción para aquellos que ya estén usando la biblioteca Underscore.js en su script. Underscore.js tiene una función isArray () (ver http://underscorejs.org/#isArray).
_.isArray(object)
Devuelve verdadero si el objeto es una matriz.
Respondido el 28 de Septiembre de 15 a las 14:09
11
Si está usando Angular, puede usar la función angular.isArray ()
var myArray = [];
angular.isArray(myArray); // returns true
var myObj = {};
angular.isArray(myObj); //returns false
respondido 19 mar '14, 08:03
También puede usar navegadores no específicos de Angular, pero solo IE9 + y todos los navegadores estándar: Array.isArray(myArray); //returns true Array.isArray(myObj); //returns false - PDA
9
En Crockford's JavaScript Las buenas partes, hay una función para verificar si el argumento dado es una matriz:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
El explica:
Primero, preguntamos si el valor es verdadero. Hacemos esto para rechazar valores nulos y otros valores falsos. En segundo lugar, preguntamos si el tipo de valor es 'objeto'. Esto será cierto para objetos, matrices y (extrañamente) nulos. En tercer lugar, preguntamos si el valor tiene una propiedad de longitud que sea un número. Esto siempre será cierto para las matrices, pero generalmente no para los objetos. Cuarto, preguntamos si el valor contiene un método de empalme. Esto nuevamente será cierto para todas las matrices. Finalmente, preguntamos si la propiedad length es enumerable (¿la longitud será producida por un bucle for in?). Eso será falso para todas las matrices. Esta es la prueba más confiable de matriz que he encontrado. Es una pena que sea tan complicado.
Respondido el 03 de diciembre de 13 a las 03:12
Y esas fueron solo las partes buenas. Imagínese cuando se publique "JavaScript The Bad Parts" ... - francescomm
5
La solución universal está a continuación:
Object.prototype.toString.call(obj)=='[object Array]'
A partir de ECMAScript 5, una solución formal es:
Array.isArray(arr)
Además, para las antiguas bibliotecas de JavaScript, puede encontrar la siguiente solución, aunque no es lo suficientemente precisa:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
Las soluciones son de http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript
Respondido el 11 de enero de 15 a las 14:01
3
código referido desde https://github.com/miksago/Evan.js/blob/master/src/evan.js
var isArray = Array.isArray || function(obj) {
return !!(obj && obj.concat && obj.unshift && !obj.callee);};
Respondido 08 Jul 11, 16:07
¿Por qué pruebas ambos concat
e unshift
, no sería suficiente para probar unshift
? - marco demaio
Cuantos más métodos comprobemos que Array tiene el movimiento, es probable que realmente sea una matriz. Otros objetos pueden tener concat
or unshift
pero es menos probable que tenga ambos. - Kris
2
Estaba usando esta línea de código:
if (variable.push) {
// variable is array, since AMAIK only arrays have push() method.
}
Respondido el 06 de enero de 13 a las 08:01
Esta no es una buena solución en absoluto. Con esta "solución" cualquier objeto con una propiedad push
eso es verdad se considerará una matriz. - teleescalador
2
Para aquellos que codifican golf, una prueba poco confiable con la menor cantidad de caracteres:
function isArray(a) {
return a.map;
}
Esto se usa comúnmente al atravesar / aplanar una jerarquía:
function golf(a) {
return a.map?[].concat.apply([],a.map(golf)):a;
}
input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Respondido 24 Oct 13, 19:10
1
Me gustó la respuesta de Brian:
function is_array(o){
// make sure an array has a class attribute of [object Array]
var check_class = Object.prototype.toString.call([]);
if(check_class === '[object Array]') {
// test passed, now check
return Object.prototype.toString.call(o) === '[object Array]';
} else{
// may want to change return value to something more desirable
return -1;
}
}
pero podrías hacer lo siguiente:
return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
Respondido 20 Abr '13, 18:04
1
He creado este pequeño código, que puede devolver tipos verdaderos.
Todavía no estoy seguro del rendimiento, pero es un intento de identificar correctamente el tipo de.
https://github.com/valtido/better-typeOf También escribí un poco sobre esto aquí. http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof/
funciona, similar al typeof actual.
var user = [1,2,3]
typeOf(user); //[object Array]
Creo que puede necesitar un poco de ajuste fino, y teniendo en cuenta las cosas, no lo he encontrado ni lo he probado correctamente. por lo que se agradecen más mejoras, ya sea en términos de rendimiento o de informes incorrectos de typeOf.
Respondido 28 Jul 14, 10:07
1
Creo que usar myObj.constructor == Object y myArray.constructor == Array es la mejor manera. Es casi 20 veces más rápido que usar toString (). Si extiendes objetos con tus propios constructores y quieres que esas creaciones también se consideren "objetos", esto no funciona, pero por lo demás es mucho más rápido. typeof es tan rápido como el método constructor pero typeof [] == 'object' devuelve verdadero, lo que a menudo no es deseable. http://jsperf.com/constructor-vs-tostring
una cosa a tener en cuenta es que null.constructor arrojará un error, por lo que si está buscando valores nulos, primero tendrá que hacer if (testThing! == null) {}
Respondido 24 ago 14, 21:08
-6
Dado que la propiedad .length es especial para matrices en javascript, simplemente puede decir
obj.length === +obj.length // true if obj is an array
Underscorejs y varias otras bibliotecas utilizan este breve y sencillo truco.
respondido 02 mar '14, 18:03
¿Le importaría explicar cómo funciona? Básicamente, ¿qué hace el '+'? - Andy McCluggage
Esto es bueno, pero también es cierto cuando el objeto es una función o una cadena, así como cualquier otro objeto con longitud de propiedad de tipo número. ¿Por qué? Bueno, el operador unario + en realidad lanza una variable como un número. Entonces, básicamente, están verificando si obj.length es un número. [object Object] no tiene longitud de propiedad, no está definido, por lo que cuando lanza undefined como un número, se convierte en NaN, la comprobación anterior resulta falsa. Por lo tanto, devuelve verdadero si la longitud de la propiedad del objeto es un número, que en el caso de matrices, cadenas y funciones sería verdadero. Underscore tiene que estar haciendo más que solo esto. - Juan
-19
Algo que acabo de pensar:
if (item.length)
//This is an array
else
//not an array
Respondido 12 Feb 15, 23:02
var item = 'this_is_not_an_array'; - kev
¡Esa es una mala solución! Una cuerda también tiene una longitud. - pmrotula
En realidad, una cadena es una matriz de caracteres, por lo que, en esencia, esto funciona: Shingala94
@PatrickNijhuis - cadena es un tipo primitivo en javascript, mientras que array es un objeto. En lenguaje común, tiene razón, una cadena es una matriz de caracteres, pero en javascript, esta afirmación es incorrecta. Es una distinción importante y la razón por la que es una mala respuesta. - wahwahwah
No, una matriz de longitud cero sigue siendo una matriz. - david burton
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript arrays variables or haz tu propia pregunta.
Verificar que un objeto sea una matriz tiene algunas advertencias específicas ... La respuesta de Peter es la única que debe usar. - aleemb
@Andy Parece que mi respuesta no es la mejor. ¿Quizás debería seleccionar una respuesta diferente como aceptada? - Peter Smit
Buen punto Peter. No me había dado cuenta de que tu respuesta estaba recibiendo comentarios como este. Creo que hace mucho tiempo que comencé a usar la función JQuery.isArray al verificar matrices, y curiosamente eso se implementa de manera diferente a cualquier otra respuesta dada aquí. He marcado la respuesta popular como correcta. - Andy McCluggage
Lo siento, eso está mal. Miré un poco más profundo y (a partir de la versión 1.6.2) JQuery todavía escribe verificaciones usando comparaciones en el formulario .... toString.call (obj) === "[object Array]" - Andy McCluggage
"Esta pregunta se ha hecho antes" ... NO, esa pregunta se hizo DESPUÉS de esta - Dexygen