Quelle est la meilleure façon de savoir si un objet est une matrice?

Pour autant que je sache, il existe trois façons de savoir si un objet est un Array

isArray fonction isArray si elle est mise en œuvre

 Array.isArray() 

Par toString

 Object.prototype.toString.apply( obj ) === "[object Array]" 

Et par instanceof

 obj instanceof Array 

Y a-t-il une raison de choisir l'un sur l'autre?

Le meilleur moyen est probablement d'utiliser Array.isArray() standard, s'il est implémenté par le moteur:

 isArray = Array.isArray(myObject) 

MDN recommande d'utiliser la toString() lorsque Array.isArray n'est pas implémenté:

Compatibilité

Exécutez le code suivant avant qu'un autre code ne crée Array.isArray s'il n'est pas disponible en mode natif. Cela repose sur Object.prototype.toString étant inchangé et la résolution d'appel à la méthode native Function.prototype.call.

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

Les deux jQuery et underscore.js [source] prennent la toString() === "[object Array]" .

À moins d'avoir prouvé que le premier a des avantages significatifs pour la performance et que mon application nécessite chaque dernière once de vitesse, j'irais pour la dernière.

La raison en est la lisibilité, pure et simple.

instanceof teste si le constructeur donné (Array) est dans la chaîne prototype de l'objet, alors que votre deuxième approche vérifie uniquement le type réel de l'objet. En d'autres termes, si votre objet hérite de Array, le second test sera vrai, mais le premier sera faux. Maintenant, il n'est généralement pas fait d'hériter de Array (il ne fonctionne pas correctement dans IE), mais la marche à suivre de la chaîne prototype ajoute probablement des frais généraux (surtout si l'objet n'est pas un tableau).

Si ce que vous essayez de faire, c'est décider si un paramètre qui vous est transmis est un tableau que vous devez répéter, il y a une bonne quantité de code là-bas qui recherche simplement un attribut .length et traite comme un tableau ou un pseudo -array si cet attribut est présent.

C'est parce qu'il y a beaucoup de choses qui ne sont pas réellement des tableaux (mais qui sont des pseudo-tableaux dotés de fonctionnalités semblables au tableau) que vous voudrez peut-être que votre code traite comme un tableau. Des exemples de certains de ces types de choses sont un objet jQuery ou un nodeList renvoyé de plusieurs appels DOM. Voici un exemple de code:

 // accepts: // single DOM element // array of DOM elements // nodeList as returned from various DOM functions like getElementsByClassName // any array like object with a .length attribute and items in numeric indexes from 0 to .length-1 like a jQuery object function hideElements(input) { if (input.length !== undefined) { for (var i = 0, len = input.length; i < len; i++) { input[i].style.display = "none"; } } else { input.style.display = "none"; } return(input); } 

La fonction .each() teste également uniquement le paramètre qui lui a été transmis pour .length (et en vérifiant qu'il ne s'agit pas d'une fonction) avant de décider qu'il est quelque chose qu'il devrait itérer comme un tableau.

Si ce n'est pas le problème que vous essayez de résoudre, je peux trouver deux références à l'utilisation de la première technique:

  1. La mise en œuvre de jQuery isArray utilise la première technique.
  2. MDN (Mozilla Developer Network) recommande le premier ici .