访问对象的不可枚举属性

时间:2018-07-10 14:14:55

标签: javascript object prototype

以下问题: Object.prototype returns empty object in Node 问了

  

为什么不console.log(Object.prototype)记录预期的对象,而是返回{}

这是答案:

  

这是因为console.log [...]在对象上使用Object.keys(),并且仅返回可枚举的属性Object.prototype包含不可枚举的属性,这就是为什么它返回空节点的原因。

     

-Amrender Singh


我想知道如何输出给定对象的所有属性(例如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__也变灰了:

enter image description here

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如何处理隐藏属性?

1 个答案:

答案 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