是否有可能获得一个对象的不可枚举的inheritance属性名称?

在JavaScript中,我们有几种获取对象属性的方法,具体取决于我们想要获得的内容。

1) Object.keys() ,它返回一个ECMA5方法的对象的所有可枚举属性。

2) for...in循环,它返回一个对象的所有可枚举属性,不pipe它们是自己的属性,还是从原型链inheritance。

3) Object.getOwnPropertyNames(obj)它返回一个对象的所有属性,可枚举或不可以。

我们也有像hasOwnProperty(prop)这样的方法让我们检查一个属性是inheritance的还是属于这个对象的, propertyIsEnumerable(prop) ,顾名思义,让我们检查属性是否可枚举。

有了这些选项,就没有办法获得一个对象的非可枚举的非属性的属性,这正是我想要做的。 有没有办法做到这一点? 换句话说,我可以以某种方式获得inheritance的非枚举属性的列表?

谢谢。

由于getOwnPropertyNames可以获得不可枚举的属性,因此可以使用它并将其与原型链一起使用。

 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 } 

我在Safari 5.1上testing了一下

 > 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__"] 

更新:重构了一下代码(添加了空格和花括号,并改进了函数名):

 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; } 

(enum / nonenum,self / inherited .. 请确认..

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

为了获得一些实例的所有inheritance的属性或方法,你可以使用这样的东西

 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(",")); 

这是我在研究这个主题的时候提出的解决scheme。 要获取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; } 

使用示例:

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

如果您正在尝试logging父对象ex的非枚举属性。 默认情况下,es6中的类中定义的方法在原型上设置,但设置为不可枚举。

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

利用集合导致一个更清洁的解决scheme,国际海事组织。

 const own = Object.getOwnPropertyNames; const proto = Object.getPrototypeOf; function getAllPropertyNames(obj) { const props = new Set(); do own(obj).forEach(p => props.add(p)); while (obj = proto(obj)); return Array.from(props); }