171 votes

Que signifie "énumérable" ?

J'ai été dirigé vers le site de MDN pour en page quand il a dit, "for..in Itère sur les propriétés énumérables d'un objet."

Ensuite, je suis allé à la Page sur l'énumérabilité et la propriété des biens où il est dit "Les propriétés énumérables sont celles qui peuvent être itérées par une boucle for..in".

Le dictionnaire définit énumérable comme dénombrable, mais je n'arrive pas vraiment à visualiser ce que cela signifie. Pourrais-je avoir un exemple de quelque chose qui est énumérable ?

179voto

Jonathan Lonowski Points 45253

Une propriété énumérable est une propriété qui peut être incluse dans et visitée pendant for..in (ou une itération similaire de propriétés, comme les boucles Object.keys() ).

Si une propriété n'est pas identifiée comme énumérable, la boucle ignorera qu'elle se trouve dans l'objet.

var obj = { key: 'val' };

console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"

for (var key in obj)
    console.log(key); // "key"

Une propriété est identifiée comme énumérable ou non par son propre [[Enumerable]] attribut . Vous pouvez le consulter dans le cadre du le descripteur de la propriété :

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');

console.log(descriptor.enumerable); // true
console.log(descriptor.value);      // 1

console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }

A for..in La boucle itère ensuite sur les noms des propriétés de l'objet.

var foo = { bar: 1, baz: 2};

for (var prop in foo)
    console.log(prop); // outputs 'bar' and 'baz'

Mais, n'évalue que sa déclaration - console.log(prop); dans ce cas - pour les propriétés dont [[Enumerable]] L'attribut est true .

Cette condition est en place parce que les objets ont beaucoup plus de propriétés notamment de l'héritage :

console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]

Chacune de ces propriétés est encore existe sur l'objet :

console.log('constructor' in foo); // true
console.log('toString' in foo);    // true
// etc.

Mais, ils sont ignorés par le for..in parce qu'ils ne sont pas énumérables.

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');

console.log(descriptor.enumerable); // false

53voto

carpeliam Points 1528

Si vous créez un objet via myObj = {foo: 'bar'} ou quelque chose comme ça, toutes les propriétés sont énumérables. La question la plus simple à poser est donc : qu'est-ce qui n'est pas énumérable ? Certains objets ont des propriétés non énumérables, par exemple si vous appelez Object.getOwnPropertyNames([]) (qui renvoie un tableau de toutes les propriétés, énumérables ou non, sur []), il retournera ['length'] qui comprend la propriété non dénombrable d'un tableau, "longueur".

Vous pouvez créer vos propres propriétés non dénombrables en appelant Object.defineProperty :

var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'

Cet exemple emprunte beaucoup à Propriétés non dénombrables en JavaScript mais montre un objet en cours d'énumération. Les propriétés peuvent être ou ne pas être accessibles en écriture, configurables ou énumérables. John Resig en parle dans la portée de Objets et propriétés ECMAScript 5 .

Et, il y a une question sur Stack Overflow concernant Pourquoi vouloir rendre les propriétés non-numérables ? .

40voto

Gabriel Kunkel Points 1404

C'est beaucoup plus ennuyeux que quelque chose qui devrait être visualisé.

Il y a littéralement un attribut sur toutes les propriétés appelé "enumerable". Lorsqu'il est défini à false, la for..in ignorera cette propriété, faisant comme si elle n'existait pas.

Il y a beaucoup de propriétés sur les objets qui ont "enumerable" mis à false, comme "valueOf" et "hasOwnProperty", parce qu'il est supposé que vous ne voulez pas que le moteur JavaScript itère sur ceux-ci.

Vous pouvez créer vos propres propriétés non énumérables à l'aide de la fonction Object.defineProperty méthode :

  var car = {
    make: 'Honda',
    model: 'Civic',
    year: '2008',
    condition: 'bad',
    mileage: 36000
  };

  Object.defineProperty(car, 'mySecretAboutTheCar', {
    value: 'cat pee in back seat',
    enumerable: false
  });

Maintenant, le fait qu'il y ait même un secret sur la voiture est caché. Bien sûr, ils peuvent toujours accéder directement à la propriété et obtenir la réponse :

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat'

Mais, ils doivent d'abord savoir que la propriété existe, parce que s'ils essaient d'y accéder à travers for..in ou Object.keys elle restera totalement secrète :

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']

Ils auraient dû juste l'appeler, "pourInAble".

10voto

Ved Points 95

Je vais écrire une ligne de définition de ENUMERABLE

Enumerable : Indique si la propriété peut être renvoyée dans une boucle for/in.

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]

9voto

Paul S. Points 20115

Si vous avez des difficultés à visualiser "ce que signifie être dénombrable", pourquoi ne pas vous demander "ce que signifie être" ? non dénombrable ?

Je pense à ça un peu comme ça, un non dénombrable propriété existe mais est partiellement caché ce qui signifie que non dénombrable est le plus bizarre. Maintenant, vous pouvez imaginer que l'énumérable est ce qui reste - la propriété la plus naturelle que nous sommes habitués à rencontrer depuis que nous avons découvert Objets . Considérons

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird

Maintenant dans un for..in imaginez que c'est comme ça pseudo-code

for property in o:
    if not property enumerable continue // skip non-enumerable, "bar"
    else do /* whatever */              // act upon enumerable, "foo"

où le corps de la boucle que vous avez tapé en JavaScript est à la place de /* whatever */

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X