Longueur d'un objet JavaScript


2384

J'ai un objet JavaScript, existe-t-il un moyen intégré ou accepté de meilleures pratiques pour obtenir la longueur de cet objet?

const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

15
Les littéraux d'objets en javascript sont par défaut des tableaux associatifs, par exemple object.propertyName.propertyValue est identique à object [propertyName] [propertyValue]
neitony

6
Ajout d'un one-liner dans Underscore.js qui fait cela: stackoverflow.com/a/11346637/11236
ripper234

31
Une fois la réponse en ligne utilisée, utilisez Object.keys (myArray) .length comme l'a dit @aeosynth.
Ranadheer Reddy

67
ok, que diriez-vousObject.keys(obj).length
Muhammad Umer

5
Pourquoi object.length n'est-il pas valide? Il renvoie le résultat correct pour moi.
Adrian M

Réponses:


2624

La réponse la plus robuste (c'est-à-dire qui capture l'intention de ce que vous essayez de faire tout en causant le moins de bogues) serait:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myObj);

Il y a une sorte de convention en JavaScript selon laquelle vous n'ajoutez rien à Object.prototype , car cela peut casser les énumérations dans diverses bibliothèques. Cependant, ajouter des méthodes à Object est généralement sûr.


Voici une mise à jour à partir de 2016 et un déploiement généralisé d'ES5 et au-delà. Pour IE9 + et tous les autres navigateurs modernes ES5 +, vous pouvez utiliser Object.keys()le code ci-dessus comme suit:

var size = Object.keys(myObj).length;

Cela ne doit modifier aucun prototype existant car il Object.keys()est maintenant intégré.

Edit : les objets peuvent avoir des propriétés symboliques qui ne peuvent pas être retournées via la méthode Object.key. La réponse serait donc incomplète sans les mentionner.

Le type de symbole a été ajouté au langage pour créer des identificateurs uniques pour les propriétés des objets. Le principal avantage du type Symbol est la prévention des écrasements.

Object.keysou Object.getOwnPropertyNamesne fonctionne pas pour les propriétés symboliques. Pour les retourner, vous devez utiliser Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

65
@Tres - votre code peut être cassé si quelqu'un vient outrepasser la propriété 'size' sans savoir que vous l'avez déjà déclarée quelque part dans le code, il vaut donc toujours la peine de vérifier si elle est déjà définie
vsync

19
@vsync Vous avez très raison. Il faut toujours mettre en œuvre les vérifications de santé mentale nécessaires :)
Tres

132
Pourquoi tout le monde ignore-t-il cela: Object.keys(obj).length
Muhammad Umer

33
@MuhammadUmer Probablement parce que cette méthode n'existait même pas lorsque cette réponse a été écrite. Même aujourd'hui, son utilisation nécessitera probablement un polyfill pour les anciens navigateurs.
Chris Hayes

21
@stonyau IE8, IE9, IE10 sont des navigateurs morts qui ne sont pas pris en charge par Microsoft. Les utilisateurs d'IE8, IE9 et IE10 reçoivent une notification de Microsoft leur indiquant qu'ils utilisent un ancien navigateur non pris en charge et doivent s'attendre à ce que ces éléments ne fonctionnent pas pour eux. support.microsoft.com/en-us/kb/3123303
Lukas Liesis

1709

Si vous savez que vous n'avez pas à vous soucier des hasOwnPropertycontrôles, vous pouvez le faire très simplement:

Object.keys(myArray).length

23
pourquoi pas? d'après ce que je sais, c'est une norme: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
vsync

104
Ce n'est pas une méthode universellement implémentée , mais vous pouvez vérifier quel navigateur la prend en charge avec ce tableau .
aeosynth

51
Pas de support IE8 = non.
ripper234

22
il est temps de passer à firefox = malheureusement, votre changement ne signifie pas que les utilisateurs de votre site Web le feront ...
mdup

82
@ ripper234 pas de support IE = temps de polyfill
John Dvorak

287

Mise à jour : si vous utilisez Underscore.js (recommandé, c'est léger!), Alors vous pouvez simplement faire

_.size({one : 1, two : 2, three : 3});
=> 3

Sinon , et vous ne voulez pas jouer avec les propriétés d'objet pour une raison quelconque, et utilisez déjà jQuery, un plugin est également accessible:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

7
_.size()était la solution parfaite pour mon projet Meteor , qui prend en charge underscore.js.
tokyovariable

4
J'utilise le soulignement et ce message m'a juste rappelé que je ne l'utilisais pas assez dans ce projet. Si vous gérez des objets, vous devriez avoir underscore.js disponible.
jbolanos

3
Underscore> (all - ['lo-dash'])
Rayjax

underscorejs, les choses qui devraient être sous js :)
minhajul

1
@Babydead pour distinguer les propriétés réelles de l'objet de celles héritées. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
ripper234

56

Voici la solution la plus multi-navigateurs.

C'est mieux que la réponse acceptée car elle utilise des Object.keys natifs s'il existe. Ainsi, c'est le plus rapide pour tous les navigateurs modernes.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

6
Object.keys()renvoie un tableau qui contient uniquement les noms des propriétés énumérables. Si vous voulez un tableau avec TOUTES les propriétés, vous devez utiliser à la Object.getOwnPropertyNames()place. Voir developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
John Slegers

35

Je ne suis pas un expert JavaScript, mais il semble que vous deviez parcourir les éléments et les compter car Object n'a pas de méthode de longueur:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey: Pour être honnête avec l'OP, la documentation JavaScript se réfère en fait explicitement à l'utilisation de variables de type Object de cette manière en tant que "tableaux associatifs".


8
Ne fonctionnera pas, car il comptera également les méthodes qui sont ajoutées via le prototype.
Lajos Meszaros,

30

Cette méthode obtient tous les noms de propriétés de votre objet dans un tableau, vous pouvez donc obtenir la longueur de ce tableau qui est égale à la longueur des clés de votre objet.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

La méthode de clés @PatrickRoberts ne renvoie pas les propriétés de la chaîne de prototypes. Alors pourquoi le besoin de hasOwnProperty ici. GetOwnProperty retournera également les propriétés cachées, car la longueur est dans le tableau, etc.
Muhammad Umer

24

Pour ne pas jouer avec le prototype ou un autre code, vous pouvez créer et étendre votre propre objet:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Si vous utilisez toujours la méthode add, la propriété length sera correcte. Si vous craignez que vous ou d'autres personnes l'utilisiez, vous pouvez également ajouter le compteur de propriétés que les autres ont publié dans la méthode de longueur.

Bien sûr, vous pouvez toujours remplacer les méthodes. Mais même si vous le faites, votre code échouera probablement sensiblement, ce qui facilitera le débogage. ;)


Je pense que c'est la meilleure solution car elle ne nécessite pas de boucle avec 'for', ce qui pourrait être coûteux si la baie est grande
Emeka Mbah

20

Voici comment et n'oubliez pas de vérifier que la propriété n'est pas sur la chaîne prototype:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;

20

Utilisez-le simplement pour obtenir length:

Object.keys(myObject).length

7
veuillez expliquer en quoi votre réponse diffère de stackoverflow.com/a/6700/8632727
Patata

3
Vous ne devriez pas non plus vraiment nommer votre objetmyArray
Barry Michael Doyle

2
@BarryMichaelDoyle j'ai changé ça :)
saurabhgoyal795

Bon, il vaut toujours mieux nommer vos variables en fonction de ce qu'elles sont réellement. Rend votre code plus lisible pour les autres développeurs.
Barry Michael Doyle

4
Avant la modification de "myArray" -> "myObject", celle-ci était identique à la deuxième réponse la plus élevée.
Yunnosch

16

Voici une solution complètement différente qui ne fonctionnera que dans les navigateurs plus modernes (IE9 +, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)

Voir jsFiddle

Configurez votre classe de tableau associatif

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Vous pouvez maintenant utiliser ce code comme suit ...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);

Je pense que ce n'est pas sûr. Par exemple, il ne peut pas avoir d'élément avec une clé de "longueur", l'instruction a1 ["longueur"] = "Bonjour tout le monde"; ne parvient pas à stocker l'entrée. Aussi la déclaration a1 ["hasOwnProperty"] = "certains accessoires"; totalement la fonction
Panos Theof

3
@PanosTheof Je ne pense pas que vous voudriez qu'il stocke la valeur si vous utilisez la lengthpropriété, tout code qui l'utilise devra s'assurer qu'il n'essaye pas de se stocker length, mais je suppose que ce serait la même chose si c'était le cas. un tableau standard aussi. Surcharger hasOwnPropertyn'importe quel objet produirait très probablement un résultat indésirable.
Ally

16

<script>
myObj = {"key1" : "Hello", "key2" : "Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
</script>

<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>

Cela fonctionne pour moi:

var size = Object.keys(myObj).length;

15

Dans certains cas, il est préférable de simplement stocker la taille dans une variable distincte. Surtout, si vous ajoutez au tableau un élément en un seul endroit et pouvez facilement augmenter la taille. Cela fonctionnerait évidemment beaucoup plus rapidement si vous devez vérifier la taille souvent.


15

Utilisation:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)


14

@palmsey: Pour être juste avec l'OP, les documents javascript se réfèrent en fait explicitement à l'utilisation de variables de type Object de cette manière en tant que "tableaux associatifs".

Et pour être honnête avec @palmsey, il avait tout à fait raison, ce ne sont pas des tableaux associatifs, ce sont certainement des objets :) - faire le travail d'un tableau associatif. Mais en ce qui concerne le point plus large, vous semblez définitivement en avoir le droit selon cet article plutôt fin que j'ai trouvé:

Les «tableaux associatifs» JavaScript considérés comme nuisibles

Mais d'après tout cela, la réponse acceptée n'est-elle pas en soi une mauvaise pratique?

Spécifiez une fonction prototype size () pour Object

Si autre chose a été ajouté au Object .prototype, le code suggéré échouera:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

Je ne pense pas que cette réponse devrait être acceptée car elle ne peut pas être approuvée pour fonctionner si vous avez un autre code en cours d'exécution dans le même contexte d'exécution. Pour le faire de manière robuste, vous devez sûrement définir la méthode de taille dans myArray et vérifier le type des membres à mesure que vous les parcourez.


13

Si vous avez besoin d'une structure de données associative qui expose sa taille, mieux utiliser une carte au lieu d'un objet.

const myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3

11

Et quelque chose comme ça -

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}

11

Si nous avons le hachage

hash = {"a": "b", "c": "d"};

nous pouvons obtenir la longueur en utilisant la longueur des clés qui est la longueur du hachage:

clés (hachage) .longueur


2
C'est une excellente réponse, mais je ne trouve aucune documentation pour cette fonction de touches. Je ne peux donc pas avoir confiance en la prise en charge de plusieurs navigateurs.
chim

1
Malheureusement, ce n'est pas une aussi bonne réponse que je ne le pensais! Il s'avère que la fonction de touches n'est disponible que dans les consoles Web Chrome et Firefox. Si vous mettez ce code dans un script, il échouera avec Uncaught ReferenceError: les clés ne sont pas définies
chim


1
En quoi est-ce différent de la réponse d' Aeosynth ?
Peter Mortensen

11
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values ​​(myObject) .length
  2. Object.entries (myObject) .length
  3. Object.keys (myObject) .length

Lequel est le plus rapide parmi les 3 ci-dessus.
siluveru kiran kumar

Object.values ​​(myObject) .length
tdjprog

comment pouvons-nous dire qu'il Object.values ​​(myObject) .length est plus rapide est-il un exemple Merci, @tdjprog
siluveru kiran kumar

essayez simplement ceci dans la console:var myObject = {}; for (let i=0; i<10000000; i++) myObject[i] = i;
tdjprog

pourquoi Object.values ​​(myObject) .length plus rapide, alors que Object.entries (myObject) .length ne donne pas de sortie même après un certain temps, quelle est la raison ici? Merci @tdjprog
siluveru kiran kumar

10

Si vous utilisez AngularJS 1.x, vous pouvez faire les choses à la manière d'AngularJS en créant un filtre et en utilisant le code de l'un des autres exemples tels que les suivants:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

Usage

Dans votre contrôleur:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

Ou selon vous:

<any ng-expression="object | lengthOfObject"></any>

4
L'OP n'a pas demandé de version AngularJS. Ce n'est pas une réponse valable à la question.
Francisco Hodge

10

La façon la plus simple est comme ça

Object.keys(myobject).length

où mon objet est l'objet de ce que vous voulez la longueur


2
Cela semble être juste une répétition de cette réponse existante .
Pang

@Pang a accepté, et il ne fournit pas de contexte supplémentaire comme le font les autres réponses.
Mystical

8

Si vous ne vous souciez pas de la prise en charge d'Internet Explorer 8 ou d'une version antérieure, vous pouvez facilement obtenir le nombre de propriétés d'un objet en appliquant les deux étapes suivantes:

  1. Exécutez soit Object.keys()pour obtenir un tableau contenant uniquement les noms des propriétés énumérables ouObject.getOwnPropertyNames() si vous souhaitez également inclure les noms des propriétés non énumérables.
  2. Obtenez la .lengthpropriété de ce tableau.

Si vous devez effectuer cette opération plusieurs fois, vous pouvez encapsuler cette logique dans une fonction:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Comment utiliser cette fonction particulière:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Voir aussi ce violon pour une démo.


8

Utilisez Object.keys(myObject).lengthpour obtenir la longueur de l'objet / du tableau

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length); //3

8
const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length)

// o/p 3

7

Une variation de certains des éléments ci-dessus est la suivante:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

C'est une façon un peu plus élégante d'intégrer hasOwnProp.


6

Voici une version différente de la réponse de James Cogan. Au lieu de passer un argument, il suffit de créer un prototype de la classe Object et de rendre le code plus propre.

Object.prototype.size = function () {
    var size = 0,
        key;
    for (key in this) {
        if (this.hasOwnProperty(key)) size++;
    }
    return size;
};

var x = {
    one: 1,
    two: 2,
    three: 3
};

x.size() === 3;

exemple jsfiddle: http://jsfiddle.net/qar4j/1/


6
Object.prototype- mauvaise idée.
Dziad Borowy,

@tborychowski pouvez-vous expliquer pourquoi?
Mohamad

voici un article: bit.ly/1droWrG . Je ne dis pas que cela ne doit pas être fait, mais seulement que vous devez connaître toutes les répercussions avant de faire cela.
Dziad Borowy

Si vous allez étendre des prototypes intégrés ou remplir une propriété (c'est-à-dire monkey-patch), veuillez le faire correctement: pour la compatibilité ascendante, vérifiez si la propriété existe d'abord, puis rendez la propriété non énumérable afin que les propres clés des objets construits ne sont pas pollués. Pour les méthodes, utilisez des méthodes réelles . Ma recommandation: suivez ces exemples qui montrent comment ajouter une méthode qui se comporte aussi étroitement que possible comme les méthodes intégrées.
user4642212

5

Vous pouvez simplement l'utiliser Object.keys(obj).lengthsur n'importe quel objet pour obtenir sa longueur. Object.keys renvoie un tableau contenant toutes les clés d' objet (propriétés) qui peuvent être utiles pour trouver la longueur de cet objet en utilisant la longueur du tableau correspondant. Vous pouvez même écrire une fonction pour cela. Soyons créatifs et écrivons également une méthode pour cela (avec une propriété getter plus pratique):

function objLength(obj)
{
  return Object.keys(obj).length;
}

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()


3
En quoi est-ce différent de la réponse d' aeosynth ?
Peter Mortensen

C'est parce qu'il montre comment le faire en tant que fonction et méthode d'objet globale (plus orientée objet et utilise une certaine forme d'encapsulation); mais pas la réponse d'aeosynth .
Mystical

Si vous allez étendre des prototypes intégrés ou remplir une propriété (c'est-à-dire monkey-patch), veuillez le faire correctement: pour la compatibilité ascendante, vérifiez si la propriété existe d'abord, puis rendez la propriété non énumérable afin que les propres clés des objets construits ne sont pas pollués. Pour les méthodes, utilisez des méthodes réelles . Ma recommandation: suivez ces exemples qui montrent comment ajouter une méthode qui se comporte aussi étroitement que possible comme les méthodes intégrées.
user4642212

De plus, comment l'écriture d'une méthode est-elle «plus efficace»?
user4642212

5

Vous pouvez toujours faire Object.getOwnPropertyNames(myObject).lengthpour obtenir le même résultat que [].lengthpour un tableau normal.


1
Object.keys()renvoie un tableau qui contient uniquement les noms des propriétés énumérables. Si vous voulez un tableau avec TOUTES les propriétés, vous devez utiliser à la Object.getOwnPropertyNames()place. Voir developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
John Slegers

3
En quoi est-ce différent de la réponse d' aeosynth ?
Peter Mortensen

4

Nous pouvons trouver la longueur de l'objet en utilisant:

Object.values(myObject).length

4

Un peu en retard dans le jeu, mais un bon moyen d'y parvenir (IE9 + uniquement) est de définir un getter magique sur la propriété length:

Object.defineProperty(Object.prototype, "length", {
    get: function () {
        return Object.keys(this).length;
    }
});

Et vous pouvez simplement l'utiliser comme ceci:

var myObj = { 'key': 'value' };
myObj.length;

Donnerait 1.


1
Mis à part les arguments contre la modification du prototype, personnellement, je n'ai JAMAIS eu de bogue causé par cela et pour moi, c'est l'un des points forts de JavaScript.
MacroMan

3

Vous trouverez ci-dessous une version de la réponse de James Coglan en CoffeeScript pour ceux qui ont abandonné le JavaScript direct :)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size

1
Vous vouliez probablement dire size++ for own key of obj( own keyétant le sucre de syntaxe dans CoffeeScript). L'utilisation hasOwnPropertydirecte à partir de l'objet est dangereuse, car elle se brise lorsque l'objet possède réellement une telle propriété.
Konrad Borowski

2
L'OP n'a pas demandé de version CoffeeScript, ni étiqueté comme tel. Ce n'est pas une réponse valable à la question.
Francisco Hodge
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.