Est-il possible d'obtenir les noms de propriété hérités non énumérés d'un objet?

En JavaScript, nous avons quelques façons d'obtenir les propriétés d'un objet, selon ce que nous voulons obtenir.

1) Object.keys() , qui renvoie toutes les propriétés propres, énumérables d'un objet, une méthode ECMA5.

2) a for...in loop, qui renvoie toutes les propriétés énumérables d'un objet, qu'il s'agisse de propriétés propres ou héritées de la chaîne de prototypes.

3) Object.getOwnPropertyNames(obj) qui renvoie toutes les propriétés d'un objet, énumérant ou non.

Nous disposons également de méthodes telles hasOwnProperty(prop) nous permet de vérifier si une propriété est héritée ou appartient réellement à cet objet et propertyIsEnumerable(prop) qui, comme son nom l'indique, nous permet de vérifier si une propriété est énumérable.

Avec toutes ces options, il n'y a aucun moyen d'obtenir une propriété non-énumérable et non- propriétaire d'un objet, ce que je veux faire. Est-ce qu'il y a un moyen de faire ça? En d'autres termes, puis-je obtenir une liste des propriétés héritées non énumérables?

Je vous remercie.

Étant donné que getOwnPropertyNames peut vous procurer des propriétés non énumérables, vous pouvez l'utiliser et l'associer à la chaîne prototype.

 function getAllProperties(obj){ var allProps = [] , curr = obj do{ var props = Object.getOwnPropertyNames(curr) props.forEach(function(prop){ if (allProps.indexOf(prop) === -1) allProps.push(prop) }) }while(curr = Object.getPrototypeOf(curr)) return allProps } 

J'ai testé cela sur Safari 5.1 et obtenu

 > getAllProperties([1,2,3]) ["0", "1", "2", "length", "constructor", "push", "slice", "indexOf", "sort", "splice", "concat", "pop", "unshift", "shift", "join", "toString", "forEach", "reduceRight", "toLocaleString", "some", "map", "lastIndexOf", "reduce", "filter", "reverse", "every", "hasOwnProperty", "isPrototypeOf", "valueOf", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "propertyIsEnumerable", "__lookupSetter__"] 

Mise à jour: Refactoré le code un peu (espaces ajoutés et accolades et amélioré le nom de la fonction):

 function getAllPropertyNames( obj ) { var props = []; do { Object.getOwnPropertyNames( obj ).forEach(function ( prop ) { if ( props.indexOf( prop ) === -1 ) { props.push( prop ); } }); } while ( obj = Object.getPrototypeOf( obj ) ); return props; } 

Et pour tout simplement tout … (énum / nonenum, self / inherited .. Veuillez confirmer …

 function getAllPropertyNames( obj ) { var props = []; do { props= props.concat(Object.getOwnPropertyNames( obj )); } while ( obj = Object.getPrototypeOf( obj ) ); return props; } 

Pour obtenir toutes les propriétés ou méthodes héritées pour certaines instances, vous pourriez utiliser quelque chose comme ça

 var BaseType = function () { this.baseAttribute = "base attribute"; this.baseMethod = function() { return "base method"; }; }; var SomeType = function() { BaseType(); this.someAttribute = "some attribute"; this.someMethod = function (){ return "some method"; }; }; SomeType.prototype = new BaseType(); SomeType.prototype.constructor = SomeType; var instance = new SomeType(); Object.prototype.getInherited = function(){ var props = [] for (var name in this) { if (!this.hasOwnProperty(name) && !(name == 'constructor' || name == 'getInherited')) { props.push(name); } } return props; }; alert(instance.getInherited().join(",")); 

Voici la solution que j'ai vécue tout en étudiant le sujet. Pour obtenir toutes les propriétés non-nominatives non énumérées de l'objet obj getProperties(obj, "nonown", "nonenum");

 function getProperties(obj, type, enumerability) { /** * Return array of object properties * @param {String} type - Property type. Can be "own", "nonown" or "both" * @param {String} enumerability - Property enumerability. Can be "enum", * "nonenum" or "both" * @returns {String|Array} Array of properties */ var props = Object.create(null); // Dictionary var firstIteration = true; do { var allProps = Object.getOwnPropertyNames(obj); var enumProps = Object.keys(obj); var nonenumProps = allProps.filter(x => !(new Set(enumProps)).has(x)); enumProps.forEach(function(prop) { if (!(prop in props)) { props[prop] = { own: firstIteration, enum_: true }; } }); nonenumProps.forEach(function(prop) { if (!(prop in props)) { props[prop] = { own: firstIteration, enum_: false }; } }); firstIteration = false; } while (obj = Object.getPrototypeOf(obj)); for (prop in props) { if (type == "own" && props[prop]["own"] == false) { delete props[prop]; continue; } if (type == "nonown" && props[prop]["own"] == true) { delete props[prop]; continue; } if (enumerability == "enum" && props[prop]["enum_"] == false) { delete props[prop]; continue; } if (enumerability == "nonenum" && props[prop]["enum_"] == true) { delete props[prop]; } } return Object.keys(props); } 
 function getNonEnumerableNonOwnPropertyNames( obj ) { var oCurObjPrototype = Object.getPrototypeOf(obj); var arReturn = []; var arCurObjPropertyNames = []; var arCurNonEnumerable = []; while (oCurObjPrototype) { arCurObjPropertyNames = Object.getOwnPropertyNames(oCurObjPrototype); arCurNonEnumerable = arCurObjPropertyNames.filter(function(item, i, arr){ return !oCurObjPrototype.propertyIsEnumerable(item); }) Array.prototype.push.apply(arReturn,arCurNonEnumerable); oCurObjPrototype = Object.getPrototypeOf(oCurObjPrototype); } return arReturn; } 

Exemple d'utilisation:

 function MakeA(){ } var a = new MakeA(); var arNonEnumerable = getNonEnumerableNonOwnPropertyNames(a); 

Si vous essayez de saisir des propriétés non énumérables d'un objet parent ex. Par défaut, les méthodes définies dans une classe dans es6 sont définies sur un prototype mais sont définies comme non énumérées.

 Object.getOwnPropertyNames(Object.getPrototypeOf(obj));