(节点版本'4.2.1',v8'4.5.103.35')
var TE = class tError extends Error {
constructor(message) {
super(message);
this.name = tError.name;
Error.captureStackTrace(this, tError);
}
static prepareStackTrace() {
console.log('run is prepareStackTrace');
return 'MyPrepareStack'
}
get stack() {
console('getter stack');
return 'MyStack';
}
};
TE.stackTraceLimit = 1;
console.log('ErrorPrepare:', TE.prepareStackTrace);
var e = new TE('MyError');
console.log('ErrorName: ', e.name);
console.log('ErrorStack: ', e.stack);
输出:
D:\>node ./Error
ErrorPrepare: prepareStackTrace() {
console.log('run is prepareStackTrace');
return 'MyPrepareStack'
}
ErrorName: tError
ErrorStack: tError: MyError
at Object.<anonymous> (D:\Error.js:23:9)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:467:10)
at startup (node.js:134:18)
at node.js:961:3
在本机属性和方法上没有工作类getter。未调用类声明中指定的函数。
如何修改本机类中的本机属性和本机行为?
答案 0 :(得分:0)
因此您在使用本机 Error.prepareStackTrace
时不会继承。事实上,Error.prepareStackTrace
的工作方式与您在标准 ES JavaScript 库中看到的典型 API 完全不同,这是因为它是原生的。通常(或历史上)JavaScript 会实现回调来分配格式化数据的函数,但因为我们正在配置 V8 使用的函数,何时可以为此使用回调。
简单来说,为了让答案尽可能简短:Native 意味着 V8 可以识别它,并且可以使用它。 V8 无法识别大多数 JavaScript 内容,因为它定义了它,但错误是任何语言的基本组成部分,这也是为什么错误格式在 V8 JavaScript 环境(Chrome 和 Node.js)中是原生的一个重要部分。 JavaScript 中的堆栈跟踪必须默认格式化,据我所知,大多数 JS 引擎只传递一个不可定制的字符串作为堆栈跟踪,无论我们在什么 JavaScript 环境中传播和拦截,我们看到的字符串都是一样的错误。这样浏览器制造商(或开发人员)和 JS RTE 软件工程师都可以以相同的方式解析堆栈跟踪,从而使 JS 错误兼容几乎没有空间,如果有的话,出现问题。 (我希望我解释得很好。)
因此,没有继承,Error.prepareStackTrace 的工作方式在下面我在 2016 年写的东西中进行了解释,大约是在问这个问题的时候。到 2021 年的今天,它仍然是相关的。
我写了一个笔记列表,详细描述了如何使用它,我将在下面发布。此 Error
属性有该做的和不该做的...堆栈跟踪)...所以做你的功课。
以下是我几年前写的指南文档。虽然它已经有几年的历史了,但它在今天仍然非常重要。指南注释很好地描述了 Error.prepareStackTrace
。
注释下方的一些链接在解释此主题时非常有用。
Error.prepareStackTrace
Error.prepareStackTrace
用例。
'use strict';
const callsites = () => {
const _prepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const stack = new Error().stack.slice(1);
Error.prepareStackTrace = _prepareStackTrace;
return stack;
};
Error.prepareStackTrace
是通过使用赋值运算符 (=
) 来配置的,以将函数分配给 Error.prepareStackTrace。 JavaScript 通常在这种情况下使用回调,因此,对于某些人来说,这种语法可能会让人感到尴尬。
分配给 Error.prepareStackTrace
的函数应该有两个参数。第一个参数接受错误对象,第二个参数接受*错误对象的堆栈跟踪。您不会调用 Error.prepareStackTrace
的分配函数 ever -- 每次捕获堆栈跟踪时,V8 引擎都会调用 Error.prepareStackTrace
(更多关于捕获堆栈跟踪的信息如下) ).
Error.captureStackTrace
方法负责捕获堆栈跟踪。
Error.prepareStackTrace
和 Error.captureStackTrace
都是原生 V8 JavaScript 函数,都可用于 Node.js RTE(在 v16.2.0 期间编写)。浏览器不支持这两种功能。
如上所述,Error.prepareStackTrace
由 V8 引擎自动调用。发生这种情况时,分配给 Error.prepareStackTrace
的函数参数会自动传递其参数。参数包括一个错误对象,以及错误对象的堆栈跟踪(这也在上面说明,如果你的困惑是因为你跳来跳去,没有按顺序阅读列表。)
上面代码片段返回的堆栈可以通过以下方法调用来操作,只要数据可用即可。仅仅因为该方法可用并不意味着该方法的数据可用。
以下是可用于错误返回的堆栈跟踪的调用站点方法列表,并由 Error.prepareStackTrace
的指定函数格式化。
据我所知:“一旦调用堆栈被捕获,在被捕获时调用堆栈中的每一帧都会成为一个调用站点,下面的方法列表是 V8 CallSite API——API用于提取存储在调用站点中的任何数据。"
NPM Module that implements Error.prepareStackTrace for you. -- 大多数人都选择这条路线,因为如果你决定喜欢它,并且你开始在所有项目中使用它,那么每次下载模块都会变得更容易,而不是重写它,或者尝试为它维护自己的模块。我在上面发布的代码片段与此 NPM 模块使用的代码片段相同,它是一个代码片段,您可以在 Codota、StackOVerflow 和其他地方找到不同版本的代码片段。研究并学习我上面发布的代码片段,您将掌握原生 V8 错误属性。