打印对象的所有隐藏属性

Ran*_*lue 6 javascript

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

for(b in a) {
   console.log(b);
}
Run Code Online (Sandbox Code Playgroud)

我不明白看到"隐藏属性",如__defineGetter__,hasOwnProperty等.

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

T.J*_*der 13

你所追求的是一个对象的非可枚举属性(可能是它从原型继承的那些).我不相信有任何标准方法可以通过JavaScript获取它们.

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

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

我正在使用谷歌Chrome 17,我看到的唯一属性console.log__proto__.

对.{}完全没有属性,只是一个原型.如果单击左侧的小箭头__proto__,它将显示您__proto__的属性.hasOwnProperty,toString等等,所有属性{}都来自原型(即Object.prototype),而不是对象本身的属性.

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

这是一个例子:

这是构造函数.如果我们new Foo用来创建一个对象,我们在JavaScript引擎将分配的原型上放置一个属性.

function Foo() {
}
Foo.prototype.bar = 42;
Run Code Online (Sandbox Code Playgroud)

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

var f = new Foo();
Run Code Online (Sandbox Code Playgroud)

f 完全没有属性,但是:

console.log(f.bar); // 42
Run Code Online (Sandbox Code Playgroud)

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

现在让我们给f它自己的"酒吧"属性:

f.bar = 67;
console.log(f.bar); // 67
Run Code Online (Sandbox Code Playgroud)

现在让我们删除 f 's"bar"属性:

delete f.bar;
Run Code Online (Sandbox Code Playgroud)

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

console.log(f.bar);
Run Code Online (Sandbox Code Playgroud)

如果你说42,你获得最高分.因为f不再有一个名为"bar"的属性,我们回过头来从原型中获取它.

请注意,这种关系是实时的,因此:

Foo.prototype.bar = 96;
console.log(f.bar); // 96
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 5

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
Run Code Online (Sandbox Code Playgroud)

因此,我们得出结论:

  • Object.keys() 不上链,也不显示非枚举
  • for in 上链,但不显示非枚举

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

为的情况下Object__defineGetter__hasOwnProperty是的性质Object.prototype上找到new Object通过原型链查找对象。因此,您可以获得:

console.log(Object.getOwnPropertyNames(Object.prototype))
Run Code Online (Sandbox Code Playgroud)

输出:

[ 'constructor',
  'toString',
  'toLocaleString',
  'valueOf',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  '__defineGetter__',
  '__lookupGetter__',
  '__defineSetter__',
  '__lookupSetter__' ]
Run Code Online (Sandbox Code Playgroud)