【发布时间】:2012-07-08 08:18:37
【问题描述】:
使用过 C 等语言的 JavaScript 开发人员经常错过使用某些类型的自省的能力,例如记录行号,以及调用当前方法的方法。好吧,如果您使用的是 V8(Chrome、Node.js),您可以使用以下内容。
【问题讨论】:
标签: javascript node.js google-chrome v8
使用过 C 等语言的 JavaScript 开发人员经常错过使用某些类型的自省的能力,例如记录行号,以及调用当前方法的方法。好吧,如果您使用的是 V8(Chrome、Node.js),您可以使用以下内容。
【问题讨论】:
标签: javascript node.js google-chrome v8
IMO 接受的答案的问题在于,当您想要打印某些内容时,您可能正在使用记录器,而在这种情况下,使用接受的解决方案将始终打印同一行 :)
一些小的改动将有助于避免这种情况!
在我们的例子中,我们使用 Winston 进行日志记录,所以 the code 看起来像这样(注意下面的 code-cmets):
/**
* Use CallSite to extract filename and number, for more info read: https://v8.dev/docs/stack-trace-api#customizing-stack-traces
* @returns {string} filename and line number separated by a colon
*/
const getFileNameAndLineNumber = () => {
const oldStackTrace = Error.prepareStackTrace;
try {
// eslint-disable-next-line handle-callback-err
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;
Error.captureStackTrace(this);
// in this example I needed to "peel" the first CallSites in order to get to the caller we're looking for
// in your code, the number of stacks depends on the levels of abstractions you're using
// in my code I'm stripping frames that come from logger module and winston (node_module)
const callSite = this.stack.find(line => line.getFileName().indexOf('/logger/') < 0 && line.getFileName().indexOf('/node_modules/') < 0);
return callSite.getFileName() + ':' + callSite.getLineNumber();
} finally {
Error.prepareStackTrace = oldStackTrace;
}
};
【讨论】:
arguments.callee.caller 的引用也是为了解决您在此处提出的问题
arguments.callee.caller 并不总是可以访问的(在我的 nodejs 应用程序中不是)。另外:eslint.org/docs/rules/no-caller 但我想在你写答案的时候使用它是可以的:)
arguments.callee 从 ES5 严格模式中移除:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Object.defineProperty(global, '__stack', {
get: function(){
var orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack){ return stack; };
var err = new Error;
Error.captureStackTrace(err, arguments.callee);
var stack = err.stack;
Error.prepareStackTrace = orig;
return stack;
}
});
Object.defineProperty(global, '__line', {
get: function(){
return __stack[1].getLineNumber();
}
});
console.log(__line);
以上将记录19。
结合arguments.callee.caller,您可以更接近通过宏在 C 中获得的有用日志类型。
【讨论】: