web-dev-qa-db-fra.com

Que signifie "énumérable"?

On m'a dirigé vers MDN for..in page quand il était dit "for..in Itère sur les propriétés énumérables d'un objet".

Ensuite, je suis allé à la page "Enumerability et propriété des propriétés où il était indiqué" 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 ne peux pas vraiment visualiser ce que cela signifie. Pourrais-je avoir un exemple de chose énumérable?

133
Patrick

Une propriété énumérable est une propriété qui peut être incluse et visitée pendant les boucles for..in (Ou une itération similaire de propriétés, comme 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 attribut [[Enumerable]] . Vous pouvez voir cela dans le cadre du 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 }

Une boucle for..in Parcourt ensuite les noms de 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 l'attribut [[Enumerable]] Est true.

Cette condition est en place car les objets ont beaucoup plus de propriétés , en particulier de l'héritage :

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

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

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

Mais, ils sont ignorés par la boucle for..in Car ils ne sont pas énumérables.

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

console.log(descriptor.enumerable); // false
131
Jonathan Lonowski

Si vous créez un objet via myObj = {foo: 'bar'} Ou quelque chose comme cela, toutes les propriétés sont énumérables. La question la plus facile à 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 inclut la propriété non énumérable d'un tableau, 'longueur'.

Vous pouvez créer vos propres propriétés non énumérables 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 énormément à propriétés non énumérables en JavaScript , mais affiche un objet énuméré. Les propriétés peuvent être ou non en écriture, configurables ou énumérables. John Resig en parle dans le cadre de Objets et propriétés ECMAScript 5 .

Et, il y a une question de débordement de pile à propos de pourquoi voudriez-vous jamais que les propriétés ne soient pas énumérables .

44
carpeliam

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é "énumérable". Lorsqu'il est défini sur false, le for..in La méthode ignorera cette propriété, prétendant qu’elle n’existe pas.

Il existe de nombreuses propriétés sur les objets pour lesquels "enumerable" est défini sur false, comme "valueOf" et "hasOwnProperty", car il est supposé que vous ne voulez pas que le moteur JavaScript vienne les parcourir.

Vous pouvez créer vos propres propriétés non énumérables en utilisant le 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 à la propriété directement et obtenir la réponse:

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

Mais ils devraient savoir que la propriété existe d’abord, car s’ils essaient d’y accéder par le biais de for..in ou Object.keys ça restera complètement secret:

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

Ils auraient juste dû l'appeler "forInAble".

33
Gabriel Kunkel

Si vous avez des difficultés à visualiser "qu'est-ce que cela signifie d'être énumérable?" pourquoi ne pas vous demander ce que signifie être non dénombrable ?

J'y pense un peu comme ceci, un non énumérable propriété existe mais est partiellement - caché; ce qui signifie que non énumérable est celui qui est étrange. Vous pouvez maintenant imaginer énumérable ce qui reste - la propriété la plus naturelle que nous ayons l'habitude de rencontrer depuis que nous avons découvert Objets . Considérer

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

Maintenant dans un for..in, imaginez-le comme pseudocode

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ée JavaScript est à la place de /* whatever */

9
Paul S.

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

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

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

les méthodes ne sont pas énumérables; ou plutôt les méthodes intégrées ne sont pas .. thos après la recherche sur quoi enumerable signifie Java; il fait simplement référence à un attribut de propriété .. tous les objets créés dans ecma3 sont énumérables, et ecma5 vous pouvez maintenant le définir .... voilà ...: D lol m’a un peu pris pour trouver la réponse, mais je crois que son livre en parle dans le livre de David Flanagan ... alors je suppose que cela signifie "caché" , ou non "caché" dans le fait que les méthodes ne sont pas montrées dans la boucle for-in, et sont donc "cachées"

0
user316264