曾经在类似C语言的编程语言中工作过的JavaScript开发者常常会想念使用某些类型的内省能力,例如记录行号以及当前方法是由哪个方法调用的。如果你正在使用V8 (Chrome, Node.js),可以采用以下方法。
曾经在类似C语言的编程语言中工作过的JavaScript开发者常常会想念使用某些类型的内省能力,例如记录行号以及当前方法是由哪个方法调用的。如果你正在使用V8 (Chrome, Node.js),可以采用以下方法。
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语言中宏定义所提供的有用日志记录。
我认为接受的答案存在问题,因为当您想要打印内容时,您可能正在使用记录器。在这种情况下,使用接受的解决方案将始终打印相同的行:)
进行一些小改动将有助于避免这种情况!
在我们的情况下,我们正在使用Winston进行记录,因此代码如下所示(请注意下面的代码注释):
/**
* 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
也可以解决你在这里提出的问题。 - james_womackarguments.callee.caller
不总是可达的(在我的nodejs应用程序中不可达)。另外:https://eslint.org/docs/rules/no-caller 但我猜你在回答时使用它是可以的 :) - Nir Alfasiarguments.callee
:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee - Jason Stewart