Pregunta ¿Cómo se comprueba si una variable es una matriz en JavaScript? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

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?


1478
2018-04-20 09:02


origen


Respuestas:


Hay varias maneras de verificar si una variable es una matriz o no. La mejor solución es la que has 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 verificar la propiedad del constructor es un proceso rápido para los motores de JavaScript.

Si tiene problemas para descubrir si una propiedad de objetos es una matriz, primero debe verificar si la propiedad está allí.

variable.prop && variable.prop.constructor === Array

Algunas otras formas son:

variable instanceof Array

Este método se ejecuta aproximadamente 1/3 de la velocidad como el primer ejemplo. Aún bastante sólido, se ve más limpio, si todo se trata de código bonito y no tanto de rendimiento. Tenga en cuenta que la comprobación de números no funciona como variable instanceof Number siempre regresa false. Actualizar: instanceof ahora va 2/3 de la velocidad!

Array.isArray(variable)

Este último es, en mi opinión, el más feo, y es uno de los más lentos. Corriendo aproximadamente 1/5 de la velocidad como el primer ejemplo. Array.prototype, en realidad es una matriz. Puedes leer más sobre esto aquí https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

Entonces, otra actualización

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

Este tipo es el más lento para tratar de buscar un Array. Sin embargo, esta es una ventanilla única para cualquier tipo que esté buscando. Sin embargo, dado que estás buscando una matriz, utiliza el método más rápido anterior.

Además, realicé algunas pruebas: http://jsperf.com/instanceof-array-vs-array-isarray/33 Así que diviértase y compruébelo.

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.


1312
2017-10-29 15:07



También puedes usar:

if (value instanceof Array) {
  alert('value is Array!');
} else {
  alert('Not an array');
}

Esto me parece una solución bastante elegante, pero para cada uno es suya.

Editar:

A partir de ES5 ahora también existe:

Array.isArray(value);

Pero esto afectará a navegadores más antiguos, a menos que esté usando polyfills (básicamente ... IE8 o similar).


982
2018-04-20 09:05



Noté que alguien mencionó jQuery, pero no sabía que había un isArray() función. Resulta que fue agregado en la versión 1.3.

jQuery lo implementa como Peter sugiere:

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

Después de haber puesto mucha fe en jQuery (especialmente sus técnicas para 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.


72
2018-04-20 10:10



Hay múltiples soluciones con todas sus peculiaridades. Esta página da una buena descripción. Una posible solución es:

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

71
2018-04-20 09:08



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-shim para polifilar Array.isArray; o agregue 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 usas jQuery puedes usar jQuery.isArray(obj) o $.isArray(obj). Si usa un guión bajo puede usar _.isArray(obj)

Si no necesita detectar arrays creados 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, a pesar de que (normalmente) 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)

54
2018-01-08 07:37



Esta es una vieja pregunta, pero teniendo 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


49
2017-10-24 21:12



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;
}

Las principales menciones fallidas de Crockford son la imposibilidad 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 esto es insuficiente.


45
2018-04-20 09:07



Personalmente me gusta la sugerencia de Peter: https://stackoverflow.com/a/767499/414784 (para ECMAScript 3. Para ECMAScript 5, use Array.isArray())

Los comentarios en la publicación indican, sin embargo, que si toString() se cambia en absoluto, esa manera de verificar una matriz fallará. Si realmente quieres ser específico y asegurarte 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 6ª edición, 7.10, dice Array.isArray() se implementa utilizando Object.prototype.toString.call() en ECMAScript 5. También tenga en cuenta que si se va a preocupar por toString()La implementación cambia, también debería preocuparse de que todos los demás métodos integrados cambien también. Por que usar push()? ¡Alguien puede cambiarlo! Tal enfoque es tonto. El cheque anterior es una solución ofrecida a aquellos preocupados por toString() cambiando, pero creo que el cheque es innecesario.


26
2017-12-03 03:17



Cuando publiqué esta pregunta, la versión de JQuery que estaba usando no incluía una isArray función. Si lo hubiera hecho, probablemente lo hubiera usado confiando en que la implementación sea la mejor forma independiente de navegador para realizar este tipo de verificación en particular.

Como 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 utilizando comparaciones en cadenas en la forma

toString.call(obj) === "[object Array]"

19
2017-08-08 14:42



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.


16
2018-03-16 07:50



Si solo está tratando con EcmaScript 5 y superior, entonces puede usar el built-in Array.isArrayfunción

p.ej.,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false

13
2017-07-11 14:05