以下问题: Object.prototype
returns empty object in Node 问了
为什么不
console.log(Object.prototype)
记录预期的对象,而是返回{}
。
这是答案:
这是因为
console.log
[...]在对象上使用Object.keys()
,并且仅返回可枚举的属性。Object.prototype
包含不可枚举的属性,这就是为什么它返回空节点的原因。
我想知道如何输出给定对象的所有属性(例如Object.prototype
)。如另一个答案所示,使用getOwnPropertyNames
可以正常工作:
const ObjectPrototype = Object.getOwnPropertyNames(Object.prototype).reduce((object, name) => {
object[name] = Object.prototype[name];
return object;
}, {});
console.log(
ObjectPrototype
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我认为我可以通过这种方式提取给定对象的 hidden 属性。但是实际上,它不能完全正常工作。
这是一个更简单的示例:我正在检查的对象是对象{mykey: 'value'}
。 Chrome给了我它的属性(console.log
也给了我),但它的原型__proto__
也变灰了:
let object = { mykey: 'value' };
object = Object.getOwnPropertyNames(object).reduce((acc, name) => {
acc[name] = object[name];
return acc;
}, {});
console.log(
object
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
以上内容仅返回一个属性。我期待也有__proto__
。 有没有办法显示一个人的所有财产,包括隐藏的财产?还是我必须手动访问它:即减少Object.getOwnPropertyNames(object.__proto__)
?
PS:换句话说,Chrome如何处理隐藏属性?
答案 0 :(得分:0)
您可以编写一个函数,getAllPropertyNames()
,它遍历对象的原型链并累积每个级别的属性:
function getAllPropertyNames (o) {
let propertyNames = []
for (let proto = o; proto !== null; proto = Object.getPrototypeOf(proto)) {
propertyNames = propertyNames.concat(Object.getOwnPropertyNames(proto))
}
return propertyNames
}
console.log(getAllPropertyNames({ mykey: 'value' }))
这些属性不是隐藏的,它们只是被继承的,这就是getOwnPropertyNames()
不包含它们的原因。它们不是特定于对象,而是从Object.prototype
继承的所有内容。
我将尝试一些非常规的操作,但应产生所需的输出:
// probably could be named better
// feel free to suggest one in comments
function asEnumerable (o) {
const acc = Object.create(null)
for (let oProto = o, aProto = acc; oProto !== null; oProto = Object.getPrototypeOf(oProto), aProto = aProto.__proto__) {
for (const key of Object.getOwnPropertyNames(oProto)) {
aProto[key] = oProto[key]
}
if (Object.getPrototypeOf(oProto) !== null) {
aProto.__proto__ = Object.create(null)
}
}
return acc
}
console.log(asEnumerable({ mykey: 'value' }))
.as-console-wrapper{min-height:100%!important}
此实现确实遵守规范,因为它不会像对待__proto__
那样修改对象的继承那样对待它,而只是将其作为acc
上的普通属性,并且aProto
。