Enumerabilidad y posesión de propiedades

Las propiedades enumerables son aquellas propiedades cuyo indicador enumerable interno se establece en true, que es el valor predeterminado para las propiedades creadas mediante una asignación simple o mediante un iniciador de propiedad (propiedades definidas mediante Object.defineProperty y tal valor enumerable predeterminado a false). Se muestran numerosas propiedades en bucles

a menos que la clave de la propiedad sea Symbol. La posesión de las propiedades está determinada por si la propiedad pertenece directamente al objeto y no a su cadena prototipo. Las propiedades de un objeto también se pueden recuperar en total. Hay varios medios incorporados para detectar, iterar/enumerar y recuperar propiedades de objetos, y el gráfico que se muestra a continuación está disponible. A continuación, se muestra un código de muestra que demuestra cómo obtener las categorías faltantes.
Propiedad, enumerabilidad y posesión — métodos integrados de detección, recuperación e iteración
Funcionalidad Propia del Objeto Propia del Objeto y su cadena prototipo Solo en cadena prototipo
Detección
Enumerable No enumerable Enumerable y no enumerable

propertyIsEnumerable

hasOwnProperty

hasOwnProperty — filtrado para excluir enumerables mediante propertyIsEnumerable

hasOwnProperty
Enumerable No enumerable Enumerable y no enumerable
No disponible sin código adicional No disponible sin código adicional in
No disponible sin código adicional
Recuperación
Enumerable No enumerable Enumerable y no enumerable

Object.keys

getOwnPropertyNames

getOwnPropertySymbols

getOwnPropertyNames, getOwnPropertySymbols — filtrado para excluir enumerables usando propertyIsEnumerable

getOwnPropertyNames

getOwnPropertySymbols

No disponible sin código adicional No disponible sin código adicional
Iterable
Enumerable No enumerable Enumerable y no enumerable

Object.keys

getOwnPropertyNames

getOwnPropertySymbols

getOwnPropertyNames, getOwnPropertySymbols — filtrado para excluir enumerables usando propertyIsEnumerable

getOwnPropertyNames

getOwnPropertySymbols

Enumerable No enumerable Enumerable y no enumerable

for..in

(no incluye símbolos)

No disponible sin código adicional No disponible sin código adicional
No disponible sin código adicional

Obtención de propiedades por enumerabilidad/posesión

Ten en cuenta que este no es el algoritmo más eficiente para todos los casos, pero es útil para una demostración rápida.

  • La detección puede ocurrir por SimplePropertyRetriever.theGetMethodYouWant(obj).indexOf(prop) > -1
  • La iteración puede ocurrir por SimplePropertyRetriever.theGetMethodYouWant(obj).forEach(function (value, prop) {}); (o usa filter(), map(), etc.)
var SimplePropertyRetriever = {
    getOwnEnumerables: function(obj) {
        return this._getPropertyNames(obj, true, false, this._enumerable); 
         // O podrías usar for..in filtrado con hasOwnProperty o simplemente esto: return Object.keys(obj);
    },
    getOwnNonenumerables: function(obj) {
        return this._getPropertyNames(obj, true, false, this._notEnumerable);
    },
    getOwnEnumerablesAndNonenumerables: function(obj) {
        return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable); 
        // O simplemente usa: return Object.getOwnPropertyNames(obj);
    },
    getPrototypeEnumerables: function(obj) {
        return this._getPropertyNames(obj, false, true, this._enumerable);
    },
    getPrototypeNonenumerables: function(obj) {
        return this._getPropertyNames(obj, false, true, this._notEnumerable);
    },
    getPrototypeEnumerablesAndNonenumerables: function(obj) {
        return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
    },
    getOwnAndPrototypeEnumerables: function(obj) {
        return this._getPropertyNames(obj, true, true, this._enumerable); 
        // O podrías usar "for..in" sin filtrar
    },
    getOwnAndPrototypeNonenumerables: function(obj) {
        return this._getPropertyNames(obj, true, true, this._notEnumerable);
    },
    getOwnAndPrototypeEnumerablesAndNonenumerables: function(obj) {
        return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
    },
    // Retrollamada del supervisor de propiedad estática privada
    _enumerable: function(obj, prop) {
        return obj.propertyIsEnumerable(prop);
    },
    _notEnumerable: function(obj, prop) {
        return !obj.propertyIsEnumerable(prop);
    },
    _enumerableAndNotEnumerable: function(obj, prop) {
        return true;
    },
    // Inspirado en http://stackoverflow.com/a/8024294/271577
    _getPropertyNames: function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
        var props = [];

        do {
            if (iterateSelfBool) {
                Object.getOwnPropertyNames(obj).forEach(function(prop) {
                    if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
                        props.push(prop);
                    }
                });
            }
            if (!iteratePrototypeBool) {
                break;
            }
            iterateSelfBool = true;
        } while (obj = Object.getPrototypeOf(obj));

        return props;
    }
};

Tabla de detección

in for..in obj.hasOwnProperty obj.propertyIsEnumerable Object.keys Object.getOwnPropertyNames Object.getOwnPropertyDescriptors Reflect.ownKeys()
Enumerable true true true true true true true true
No enumerable true false true false false true true true
Símbolos clave true false true true false false true true
Enumerable heredado true true false false false false false false
Heredado no enumerable true false false false false false false false
Símbolos clave heredados true false false false false false false false

Ve también