打印对象的所有隐藏属性

Printing all the hidden properties of an object

本文关键字:隐藏 属性 对象 打印      更新时间:2023-09-26

所以我有一个空对象a = {}。当我做console.log(a)console.dir(a)甚至时

for(b in a) {
   console.log(b);
}

我看不到"隐藏属性",如__defineGetter__hasOwnProperty等。

如何打印对象的所有属性?

您想要的是对象的不可枚举属性(可能还有它从原型继承的属性)。我不相信有任何标准的方法可以通过JavaScript获得它们。

如果使用调试器并检查对象,通常会显示对象的所有属性(而不仅仅是可枚举的属性)。现在所有主流浏览器都内置了调试器:Chrome有开发工具(Ctrl+Shift+I);IE8及以上版本具有"F12开发工具";IE7及更早版本可以通过免费版本的VS.Net进行调试;最新版本的Firefox内置了工具,对于旧版本,您可以获得Firebug插件;歌剧院有蜻蜓。

更新:在对您所说问题的评论中:

我使用的是谷歌Chrome 17,使用console.log时看到的唯一属性是__proto__

对。{}根本没有任何属性,只是一个原型。如果单击__proto__左侧的小箭头,它将显示__proto__的属性。hasOwnPropertytoString等都是{}从原型(即Object.prototype)获得的属性,而不是对象本身的属性。

JavaScript使用原型继承,这意味着对象由原型支持。如果你试图检索对象没有的属性的值,JavaScript引擎会查看对象的原型,看看原型是否具有该属性;如果是,则使用该值。如果原型没有,引擎会查看原型的原型;依此类推,直到它到达层次结构的根。这就是为什么您听说对象具有自己的属性,而不是它们继承的属性。

这里有一个例子:

这是一个构造函数。如果我们使用new Foo创建一个对象,JavaScript引擎将为原型分配一个属性。

function Foo() {
}
Foo.prototype.bar = 42;

让我们使用构造函数创建一个对象:

var f = new Foo();

f完全没有属性,但是:

console.log(f.bar); // 42

因为f没有名为"bar"的属性,所以引擎会查看f的原型,即Foo.prototype对象。

现在让我们给f一个自己的"bar"属性:

f.bar = 67;
console.log(f.bar); // 67

现在让我们移除f的"bar"属性:

delete f.bar;

如果我们现在尝试检索f.bar会发生什么?

console.log(f.bar);

如果你说42,你会得到高分。因为f不再有一个名为"bar"的属性,所以我们回到原型中获取它。

请注意,这种关系是live,因此:

Foo.prototype.bar = 96;
console.log(f.bar); // 96

在ECMAScript的第三版中(大多数浏览器实现了与第三版类似的东西),将原型分配给对象的唯一方法是通过构造函数的prototype属性,如上所述。在第5版中,添加了一种更直接的方式:Object.create,您可以直接将原型对象传递给它:

var proto = {bar: 42};
var obj = Object.create(proto);
console.log(obj.bar); // 42
proto.bar = 67;
console.log(obj.bar); // 67

Object.getOwnPropertyNames(obj)

这也将显示每个不可枚举的属性,尽管它不会像.那样遵循原型链查找。

我不知道有哪种方法既能进入原型链,又能显示不可枚举对象。

示例:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})
console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]
console.log(Object.keys(o))
// [ 'not' ]
for (var x in o)
    console.log(x)
// yes, base

因此我们得出结论:

  • Object.keys()不会向上移动,也不会显示不可枚举项
  • for in向上移动,但不显示不可枚举项

当然,您可以手动爬上原型链并使用Object.getOwnPropertyNames

对于Object的情况,__defineGetter__hasOwnProperty是通过原型链查找在new Object对象上找到的Object.prototype的属性。所以你可以用获得它们

console.log(Object.getOwnPropertyNames(Object.prototype))

输出:

[ 'constructor',
  'toString',
  'toLocaleString',
  'valueOf',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  '__defineGetter__',
  '__lookupGetter__',
  '__defineSetter__',
  '__lookupSetter__' ]