¿Qué significa enumerable?

151

Me dirigieron a MDN para ... en la página cuando decía: "para ... en Itera sobre las propiedades enumerables de un objeto".

Luego fui a la página Enumerabilidad y propiedad de propiedades donde decía "Las propiedades enumerables son aquellas que pueden iterarse mediante un bucle for..in".

El diccionario define enumerable como contable, pero realmente no puedo visualizar lo que eso significa. ¿Puedo obtener un ejemplo de algo enumerable?

Patricio
fuente
¿Entiendes lo que for-inhace?
De las respuestas obtuve que for..in permite que todas las propiedades enumerables de un objeto estén disponibles para su uso con la declaración for
Patrick
66
El significado más simple es: si una propiedad será producida por un for inbucle o no (para aquellos que no quieren conocer los detalles o simplemente no les importa;))
Tomasz Racia

Respuestas:

158

Una propiedad enumerable es aquella que se puede incluir y visitar durante los for..inbucles (o una iteración similar de propiedades, como Object.keys()).

Si una propiedad no se identifica como enumerable, el bucle ignorará que está dentro del objeto.

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"

Una propiedad se identifica como enumerable o no por su propio [[Enumerable]]atributo . Puede ver esto como parte del descriptor de la propiedad :

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 }

for..inLuego, un bucle itera a través de los nombres de propiedad del objeto.

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

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

Pero, solo evalúa su declaración, console.log(prop);en este caso, para aquellas propiedades cuyo [[Enumerable]]atributo es true.

Esta condición está en su lugar porque los objetos tienen muchas más propiedades , especialmente de herencia :

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

Cada una de estas propiedades todavía existe en el objeto :

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

Pero, se saltan por el for..inciclo porque no son enumerables.

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

console.log(descriptor.enumerable); // false
Jonathan Lonowski
fuente
Por lo tanto, la propiedad del constructor no es enumerable porque no se muestra en el bucle for..in. Si bien los nombres de las propiedades, como bar o baz, son enumerables porque fue capaz de console.log cada uno desde el objeto?
Patrick
55
Esto no es del todo correcto: But, they are skipped (or not counted) by the for..in loop because they are not enumerable. De hecho, las propiedades en Object.prototypese ignoran porque están más arriba en la cadena de prototipos, no porque no sean enumerables. Ni getOwnPropertyNames()o keys()mostrar propiedades que no son un objeto de cuenta. Como nota al margen, es cierto que muchas de las propiedades incorporadas no son enumerables y, por lo tanto, no se mostrarán con keys(), pero tendrá que escribir código adicional si desea atravesar la cadena de prototipos.
Magnus
literalmente, enumerable significa contable
Christian Matthew
49

Si crea un objeto vía myObj = {foo: 'bar'}o algo por el estilo, todas las propiedades son enumerables. Entonces, la pregunta más fácil es: ¿qué no es enumerable? Ciertos objetos tienen algunas propiedades no enumerables, por ejemplo, si llama Object.getOwnPropertyNames([])(que devuelve una matriz de todas las propiedades, enumerables o no, en []), devolverá ['length'], que incluye la propiedad no enumerable de una matriz, 'longitud' .

Puede hacer sus propias propiedades no enumerables llamando a 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'

Este ejemplo se basa en gran medida en propiedades no enumerables en JavaScript , pero muestra un objeto que se enumera. Las propiedades pueden ser o no escribibles, configurables o enumerables. John Resig analiza esto en el ámbito de los objetos y propiedades de ECMAScript 5 .

Y, hay una pregunta acerca de desbordamiento de pila por qué te gustaría siempre quiere hacer las propiedades no numerable .

carpeliam
fuente
Hm, tanto votos a favor como a favor. Ciertamente, si hay algo en esta respuesta que valga la pena votar, agregue un comentario aquí.
carpeliam
1
Otra respuesta escribió esto: var o = {}; o ['foo'] = 0; // enumerable, Object.defineProperty normal (o, 'bar', {valor: 1}); // no enumerable, extraño ¿Por qué agregar explícitamente enumerable: falso?
Patrick
55
@Patrick, lo incluí aquí en parte para que quede claro en el ejemplo que es una opción, pero dependiendo de tu audiencia, ser explícito puede ser una decisión sólida para que sea claro para cualquiera que esté leyendo tu código.
carpeliam
@carpeliam Gracias por esta explicación breve y muy clara, no pude obtener una respuesta aceptada hasta que
revisé la
37

Es mucho más aburrido que algo que debería visualizarse.

Literalmente hay un atributo en todas las propiedades llamado "enumerable". Cuando se establece en falso, el for..inmétodo omitirá esa propiedad, pretenda que no existe.

Hay muchas propiedades en los objetos que tienen "enumerable" establecido en falso, como "valueOf" y "hasOwnProperty", porque se presume que no desea que el motor de JavaScript itere sobre ellos.

Puede crear sus propias propiedades no enumerables utilizando el Object.definePropertymétodo:

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

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

Ahora, el hecho de que incluso hay un secreto sobre el automóvil está oculto. Por supuesto, aún pueden acceder a la propiedad directamente y obtener la respuesta:

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

Pero, tendrían que saber que la propiedad existe primero, porque si están intentando acceder a ella for..ino Object.keyspermanecerá completamente en secreto:

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

Deberían haberlo llamado "forInAble".

Gabriel Kunkel
fuente
55
Votaron a favor de esa última línea: creo que si realmente se hubiera solicitado forInAble, nadie estaría preguntando sobre eso. Que nos lleva a mi pregunta - ¿por qué haría usted (o ¿por qué tiene que hacerlo) establecer una propiedad a no ser enumerables? La propiedad de longitud de una matriz se usa con bastante frecuencia como un ejemplo de una propiedad no enumerable, pero ¿por qué no podría simplemente establecerla como enumerable (no la restricción de JavaScript, quiero decir, por qué se estableció como no enumerable en JavaScript en El primer lugar)?
Chris
Para aclarar mi pregunta, ¿por qué se decidió que lo siguiente no era una opción? Marca: Modelo de Honda: Secreto cívico: Longitud de
Chris
Hmmm ... Puede que haya encontrado la respuesta a mi propia pregunta. De una búsqueda en Google para "¿Qué quieres decir con tipos de datos enumerados?" Los datos enumerados tienen un conjunto finito de valores. Un tipo de datos enumerados consta de valores que usted permite para ese tipo o valores enumerados. Para los tipos enumerados basados ​​en enteros, cada valor enumerado consiste en un nombre y un valor numérico subyacente. Entonces, si entiendo correctamente, dado que hay un número infinito de longitudes posibles, tendría que asignar un número infinito de nombres, un nombre a cada longitud ¿Es eso correcto?
Chris
Bueno, abordar su primera pregunta, establecer una propiedad no enumerable en un objeto es un poco hacky, ya que la única forma en que podría averiguar qué había en ese objeto sería mirar el código y como base de código desarrolla que podría ser enterrado. Entonces, en general, no querrás usarlo. Respecto a '.length' que da el número de caracteres en una cadena o elementos en una matriz es solo algo que se presume que no querríamos incluir si estuviéramos usando 'for ... in'. No puedo responder por qué los dioses de Js lo hicieron así necesariamente. Tienen razones ( ejem ) opiniones más allá de nuestra comprensión.
Gabriel Kunkel
... y no creo que pueda responder a su segunda pregunta sobre los tipos de datos enumerados, aunque parece algo que podría analizar durante un tiempo si tuviera tiempo. :-)
Gabriel Kunkel
9

Si tiene dificultades para visualizar "¿qué significa ser enumerable?" ¿Por qué no te preguntas, qué significa ser no numerable ?

Pienso un poco así, existe una propiedad no enumerable pero está parcialmente oculta ; lo que significa que no es enumerable es el extraño. Ahora puede imaginar lo enumerable como lo que queda: la propiedad más natural a la que estamos acostumbrados desde que descubrimos los Objetos . Considerar

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

Ahora en un for..in, imagínelo como pseudocódigo

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

donde el cuerpo del bucle que escribió en JavaScript está en el lugar de/* whatever */

Paul S.
fuente
8

Escribiré una definición de línea de ENUMERABLE

Enumerable: Especifica si la propiedad se puede devolver en un bucle for / in.

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

los métodos no son enumerables; o mejor dicho, los métodos incorporados no son .. después de buscar lo que significa enumerable para el script java; solo se refiere a un atributo de propiedad ... todos los objetos creados en ecma3 son enumerables, y ecma5 ahora puede definirlo ... eso es todo ...: D lol me tomó un poco encontrar la respuesta; pero creo que se menciona en el libro de David Flanagan ... así que supongo que significa "oculto", o no "oculto", ya que los métodos no se muestran en el ciclo for in, y por lo tanto están "ocultos"

usuario316264
fuente
0

Piense en el tipo de datos enum, solo una estructura de objetos que corresponden a diferentes números. Declarar algo como enumerable es declarar que corresponde a un número específico, lo que le permite tener un lugar en un Diccionario que representa componentes contables de un objeto. En pocas palabras, hacer que un objeto sea enumerable es lo mismo que decirle al compilador: "Oye, esta propiedad cuenta, quiero ver esto cuando verifico los datos de este objeto".

Jeshawn Chrite
fuente
0

Los métodos integrados que heredan los objetos no son enumerables, pero las propiedades que su código agrega a los objetos son enumerables a menos que se indique explícitamente

parveen mittal
fuente