javascript - JavaScript 错误属性在一个实例和它的原型中是不同的——怎么会这样?
问题描述
我无法理解错误属性是如何定义的。有些是在实例上定义的,有些是在原型上定义的。不应该是不可能的吗?我的意思是,我希望新创建的实例具有与原型完全相同的属性。这就是我的意思:
let err = new Error('Test');
Object.getOwnPropertyNames(err);
// Array(4) [ "fileName", "lineNumber", "columnNumber", "message" ]
Object.getOwnPropertyNames(Object.getPrototypeOf(err));
// Array(5) [ "toString", "message", "name", "stack", "constructor" ]
fileName
, lineNumber
,怎么可能columnNumber
存在于实例上,但如果实例刚刚被创建并且没有以任何方式改变,那么原型上不存在?
另外,实例没有stack
自己的属性,是因为它是不可枚举的吗?
解决方案
fileName, lineNumber, columnNumber 怎么可能存在于实例上,但如果实例刚刚创建且未以任何方式更改,则原型上不存在?
这里没有什么神奇的事情发生。Error
是一个构造函数。该函数可以在实例上创建任何属性。
例子:
class Error {
constructor() {
this.fileName = '<script>';
}
}
const err = new Error();
console.log(Object.getOwnPropertyNames(err));
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(err)));
如您所见,fileName
是仅存在于实例上的属性。
不应该是不可能的吗?我的意思是,我希望新创建的实例具有与原型完全相同的属性。
这不是它应该如何工作的。原型包含应该在所有实例之间共享的属性,而实例包含特定于该实例的属性。最后,原型只是另一个对象(实例)指向的对象。它仅在访问实例上的属性时使用。如果该属性在实例上不存在,JS 运行时将在实例的原型上查找它,等等。不多也不少。
也许你会惊讶地看到message
实例和原型。原型上的message
属性是默认的错误消息。如果错误实例没有自己的消息,则使用它(如果您没有将参数传递给Error
构造函数,则错误实例没有自己的message
属性(请参阅规范))。
const err = new Error();
console.log(Object.getOwnPropertyNames(err));
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(err)));
另外,实例没有堆栈作为自己的属性,是因为它是不可枚举的吗?
不,“自有”属性是“自有”属性,无论其可枚举性如何。stack
是一个getter/setter,因此它可以在当前实例上运行this
(或者该功能是为本地函数实现的)。
console.log(Object.getOwnPropertyDescriptor(Error.prototype, 'stack'));
// Object { get: stack(), set: stack(), enumerable: false, configurable: true }
推荐阅读
- r - 显示存储在列表中的图,禁止将名称和索引打印到控制台
- c++ - macdeployqt 不验证应用程序
- aws-amplify - Amplify Web Hosting 默认使用 CloudFront CDN 吗?
- html - 在没有 CSS 的情况下在 wordpress 上自定义表格?
- python - 如何根据出现的次数添加额外的列
- lapack - libatlas3、liblapacke 和 libopenblas0 如何相互交互?
- asp.net-web-api2 - Get方法中的多个参数
- javascript - 如何使用日期选择器更改我的 API 链接
- reactjs - ReactJS:在生产构建中处理失败的加载资源
- javascript - Discord.js 反应角色机器人不分配角色,但嵌入工作