Question

Si j'ai un objet JavaScript, dites

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

existe-t-il une meilleure pratique intégrée ou acceptée pour obtenir la longueur de cet objet ?

Était-ce utile?

La solution

La réponse la plus robuste (c.-à-d.qui capture l'intention de ce que vous essayez de faire tout en provoquant le moins de bugs) 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 existe une sorte de convention en JavaScript selon laquelle vous n'ajoutez rien à Object.prototype, car cela peut interrompre les énumérations dans diverses bibliothèques.Cependant, l’ajout de méthodes à Object est généralement sûr.


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

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

Cela ne nécessite aucune modification d'un prototype existant puisque Object.keys() est désormais intégré.

Modifier:Les objets peuvent avoir des propriétés symboliques qui ne peuvent pas être renvoyé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 identifiants uniques pour les propriétés des objets.Le principal avantage du type Symbole est la prévention des écrasements.

Object.keys ou Object.getOwnPropertyNames ne 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

Autres conseils

Si tu sais que tu n'as pas à t'inquiéter hasOwnProperty contrôles, vous pouvez faire cela très simplement :

Object.keys(myArray).length

Mis à jour:Si vous utilisez Souligner.js (recommandé, c'est léger !), alors vous pouvez simplement le faire

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

Sinon, et que vous ne voulez pas vous embêter avec les propriétés de l'objet pour une raison quelconque et que vous 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;
};

Voici la solution la plus multi-navigateurs.

C'est mieux que la réponse acceptée car elle utilise des Object.keys natifs s'ils existent.C’est donc le plus rapide de 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;

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

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

@palmsey :Par souci d'équité envers l'OP, la documentation JavaScript fait explicitement référence à l'utilisation de variables de type Object de cette manière en tant que "tableaux associatifs".

Cette méthode récupère 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

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 oubliiez de l'utiliser, vous pouvez également ajouter le compteur de propriétés que les autres ont publié à la méthode length.

Bien sûr, vous pouvez toujours écraser les méthodes.Mais même si vous le faisiez, votre code échouerait probablement sensiblement, ce qui faciliterait le débogage.;)

Le plus simple est

Object.keys(myObject).length

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

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

Utilisez-le simplement pour obtenir le length:

Object.keys(myObject).length

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 que vous pouvez facilement augmenter la taille.Cela fonctionnerait évidemment beaucoup plus rapidement si vous deviez vérifier la taille souvent.

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 Associative Array

/**
 * @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);

Utiliser:

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

@palmsey :Par souci d'équité envers l'OP, la documentation javascript fait explicitement référence à l'utilisation de variables de type Object de cette manière en tant que "tableaux associatifs".

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

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

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

Spécifiez une fonction prototype size() pour Object

Si quelque chose d'autre a été ajouté à Object .prototype, alors 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 on ne peut pas lui faire confiance pour fonctionner si vous avez un autre code exécuté dans le même contexte d'exécution.Pour le faire de manière robuste, vous devrez sûrement définir la méthode de taille dans myArray et vérifier le type des membres au fur et à mesure que vous les parcourez.

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

Si nous avons le hachage

hachage = {"a" :"avant JC":"d"};

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

clés (hachage). longueur

Si vous utilisez AngulaireJS 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 le suivant :

// 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 à votre avis :

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

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

Si vous avez besoin d'une structure de données associative qui expose sa taille, utilisez mieux une carte plutôt qu'un objet.

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

Une variante de certains des éléments ci-dessus est :

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

C'est une manière un peu plus élégante d'intégrer hasOwnProp.

Si la prise en charge d'Internet Explorer 8 ou version antérieure ne vous intéresse pas, 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 qui sont dénombrable ou Object.getOwnPropertyNames() si vous souhaitez également inclure les noms de propriétés qui ne sont pas énumérables.
  2. Obtenir le .length propriété de ce tableau.

Si vous devez le faire plusieurs fois, vous pouvez envelopper 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 également ce violon pour une démo.

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Objet.valeurs (monObjet).longueur
  2. Objet.entrées (monObjet).longueur
  3. Objet.keys(monObjet).longueur

Voici une version différente de la réponse de James Cogan.Au lieu de passer un argument, prototypez simplement la classe Object et rendez 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/

Vous pouvez simplement utiliser Object.keys(obj).length sur n'importe quel objet pour obtenir sa longueur.Object.keys renvoie un tableau contenant tout l'objet clés (propriétés) qui peuvent s'avérer utiles pour trouver la longueur de cet objet en utilisant la longueur du tableau correspondant.Vous pouvez même écrire un fonction pour ça.Obtenons créatif et écris un méthode pour cela également (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()

Le plus simple c'est comme ça

Object.keys(myobject).length

où monobjet est l'objet dont vous voulez la longueur

Tu peux toujours faire Object.getOwnPropertyNames(myObject).length pour obtenir le même résultat que [].length donnerait pour un tableau normal.

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

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

Propriété

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

Utiliser

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4

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

Object.values(myObject).length

Un peu tard dans le jeu, mais une bonne façon 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top