打印对象的所有隐藏属性

时间:2012-02-09 11:06:33

标签: javascript

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

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

我无法看到“隐藏属性”,例如__defineGetter__hasOwnProperty等。

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

2 个答案:

答案 0 :(得分:13)

您所追求的是对象的non-enumerable属性(可能还有从其原型继承的属性)。我不相信有任何标准方法可以通过JavaScript获取它们。

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

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

  

我正在使用Google 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一个自己的“酒吧”属性:

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

现在让我们删除 f的“酒吧”属性:

delete f.bar;

如果我们现在尝试检索f.bar会怎样?

console.log(f.bar);

如果你说42,你会获得最高分。因为f不再具有名为“bar”的属性,所以我们回过头来从原型中获取它。

请注意,此关系为实时,因此:

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

在ECMAScript的第3版中(大多数浏览器实现了第3版的内容),将原型分配给对象的唯一方法是通过构造函数的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

答案 1 :(得分:5)

<强> Object.getOwnPropertyNames(obj)

这也会显示每个不可枚举的属性,但它不会像.那样遵循prototype chain查找。

我不知道任何方法都会在原型链上显示并显示非枚举。

示例:

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是通过原型链查找在Object.prototype个对象上找到的new Object的属性。所以你可以得到它们:

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

输出:

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