好的,我首先想说,我知道这可能有一个非常基本的解释,所以如果这是一个太新手的问题,请原谅。
问题是:为什么在创建新原型之前Error.message属性不存在?
示例:
let a = new Error('testing')
console.log( a.message ) // 'testing'
但之前,如果我尝试访问Error属性和方法(例如:Object.getOwnPropertyNames(Error)
(,消息属性甚至不存在,甚至不是一个空字符串,它就是不存在。
它以前不应该是一个空字符串吗?在创建新原型时,Error对象如何自行创建新属性?
getOwnPropertyNames
只返回对象上设置的属性,而不是继承的(原型(属性。线索就在这个名字里:own"-属性。
举例:
const a_simple_object_with_no_prototype = {
b: "b",
c: "c"
};
console.log( Object.getOwnPropertyNames( a_simple_object_with_no_prototype ) )
// [ "b", "c" ]
对于具有从原型继承的属性的对象,我们会得到不同的结果:
const an_object_used_as_a_prototype = {
a: 789
};
function ConstructorFunction() {
this.b = "b";
}
ConstructorFunction.prototype = an_object_used_as_a_prototype;
const an_object_with_a_prototype = new ConstructorFunction();
an_object_with_a_prototype.c = "c";
console.log( Object.getOwnPropertyNames( an_object_with_a_prototype ) )
// [ "b", "c" ] // does not include "a" which is inherited from the prototype
但之前,如果我尝试访问Error属性和方法(例如:
Object.getOwnPropertyNames(Error)
(,消息属性甚至不存在,甚至不是空字符串,它就是不存在。
这是因为CCD_;静态";CCD_ 5构造函数的1个成员。如果你做Object.getOwnPropertyNames( Error.prototype )
,那么你会看到它们:
const protoProps = Object.getOwnPropertyNames( Error.prototype );
console.log( protoProps ); // ["constructor", "name", "message", "toString"]
我确实注意到,JavScript中的Error
对象充满了一些特殊的行为,这些行为在JavaScript本身中是无法复制的,比如它的stack
属性是如何工作的,但这超出了您的问题范围。
1:我使用术语";静态";在C++/Java/C#意义上,因为它是与类型而不是实例关联的字段/成员。这并不意味着属性/字段/成员是不变的、只读的或不可变的。