2012-02-09 60 views
6

所以我有空对象a = {}。当我做console.log(a)console.dir(a),甚至打印一个对象的所有隐藏属性

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

我没有能看到“隐藏属性”,如__defineGetter__hasOwnProperty

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

+0

你用什么浏览器,所以你可以用得到它们?在谷歌浏览器,我看到@antyrat我使用谷歌浏览器17,我看到使用'console.log'是'__proto__'唯一的财产对象 – antyrat 2012-02-09 11:08:23

+0

的所有属性。 – Randomblue 2012-02-09 11:09:45

+0

你可以打开这个属性,在里面你会看到所有不可枚举的属性 – antyrat 2012-02-09 11:11:17

回答

12

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

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

更新:关于该问题的意见你说:

我使用谷歌浏览器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没有一个所谓的“栏”属性,引擎看起来f的原型,这是Foo.prototype对象。

现在,让我们给f自己的 “酒吧” 属性:

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

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

delete f.bar; 

,如果我们试图取回会发生什么f.bar现在?

console.log(f.bar); 

如果你说42,你会得到最高分。由于f不再有所谓的“酒吧”的属性,我们回去从原型得到它。

注意,这种关系是现场,所以:

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

在ECMAScript中的第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 
+0

写得很好(+1),谢谢:) – nkm 2012-02-09 11:32:17

3

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__' ]