Javascript 为什么可以';我看不到错误对象的键吗?

Javascript 为什么可以';我看不到错误对象的键吗?,javascript,node.js,Javascript,Node.js,当我创建一个新的错误对象时,我可以看到它的消息或名称,但使用标准方法看不到它的键列表,这让我感到困惑。为什么呢 > err = new Error("an error") [Error: an error] > err.message 'an error' > err.name 'Error' > Object.keys(err) [] > JSON.stringify(err) '{}' JavaScript属性可能不可枚举,这意味着它们不会出现在for..in

当我创建一个新的错误对象时,我可以看到它的消息或名称,但使用标准方法看不到它的键列表,这让我感到困惑。为什么呢

> err = new Error("an error")
[Error: an error]
> err.message
'an error'
> err.name
'Error'
> Object.keys(err)
[]
> JSON.stringify(err)
'{}'

JavaScript属性可能不可枚举,这意味着它们不会出现在
for..in
循环或
Object.keys
结果中

可以使用直接获取对象上的所有属性(可枚举或不可枚举)。我之所以说“直接”,是因为普通枚举查找对象的原型链以获取父原型上的可枚举属性,而
getOwnPropertyNames
则不这样做

因此,
Object.getOwnPropertyNames(err)
仅显示

['stack',
 'arguments',
 'type',
 'message']

name
属性是
Error.prototype
的不可枚举属性,从不直接在
Error
实例上设置。(原型概述:当您尝试访问
err.name
时,查找
err
不会出现任何结果,因此解释器会查看
Error.prototype
,它确实具有
name
属性。)

尝试
Object.getOwnPropertyNames()
而不是
Object.keys()
。它们可能是不可枚举的。例如,
Object.getOwnPropertyDescriptor(err,'stack')
显示
enumerable:false
。我仍然无法在Firefox45中看到
stack
属性:
e=newerror(“Hi!”);Object.getOwnPropertyNames(e);//数组[“fileName”、“lineNumber”、“columnNumber”、“message”]
@kiroh我没有Firefox可以测试,但是
Object.getOwnPropertyNames(Object.getPrototypeOf(err))
产生了什么?可能是Firefox中的堆栈是继承的访问器属性。(使用
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(err),“stack”)
确认并检查
get
set
属性。)@apsillers谢谢!它实际上是原型的访问器属性。