Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在V8 JavaScript(Chrome&;Node.js)中访问行号_Javascript_Node.js_Google Chrome_V8 - Fatal编程技术网

在V8 JavaScript(Chrome&;Node.js)中访问行号

在V8 JavaScript(Chrome&;Node.js)中访问行号,javascript,node.js,google-chrome,v8,Javascript,Node.js,Google Chrome,V8,花时间学习C等语言的JavaScript开发人员常常无法使用某些类型的内省,例如记录行号,以及调用当前方法的方法。如果您使用的是V8(Chrome,Node.js),那么您可以采用以下方法 Object.defineProperty(global, '__stack', { get: function(){ var orig = Error.prepareStackTrace; Error.prepareStackTrace = function(_, stack){ ret

花时间学习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


结合
参数.callee.caller
您可以更接近通过宏在C中获得的有用日志记录类型。

接受的答案IMO的问题是,当您想要打印某些内容时,您可能正在使用记录器,在这种情况下,使用接受的解决方案将始终打印同一行:)

一些小的改变将有助于避免这种情况

在我们的例子中,我们使用Winston进行日志记录,所以看起来是这样的(请注意下面的代码注释):

/**
*使用CallSite提取文件名和编号,有关详细信息,请阅读:https://v8.dev/docs/stack-trace-api#customizing-堆栈跟踪
*@返回{string}文件名和由冒号分隔的行号
*/
常量GetFileName和LineNumber=()=>{
const oldStackTrace=Error.prepareStackTrace;
试一试{
//eslint禁用下一行句柄回调错误
Error.prepareStackTrace=(err,structuredStackTrace)=>structuredStackTrace;
错误。captureStackTrace(此);
//在本例中,我需要“剥离”第一个呼叫站点,以便找到我们正在寻找的呼叫方
//在代码中,堆栈的数量取决于所使用的抽象级别
//在我的代码中,我正在剥离来自logger模块和winston(node_模块)的帧
const callSite=this.stack.find(line=>line.getFileName().indexOf('/logger/')<0&&line.getFileName().indexOf('/node_modules/')<0);
返回callSite.getFileName()+':'+callSite.getLineNumber();
}最后{
Error.prepareStackTrace=oldStackTrace;
}
};

提供了v8 StackTrace API中可用的其他方法列表。一般列表:getThis、getTypeName、getFunction、getFunctionName、getMethodName、getFileName、getLineNumber、getColumnNumber、getEvalOrigin、isToplevel、isEval、isNative、IsConstructor另请参阅此答案,以获取输出整个跟踪的一些示例代码。您可以在这里看到此API的一些示例用法:@zamnuts该页面似乎不再列出这些函数中的任何函数2019年v8堆栈跟踪API文档的URL是另一个伟大的解决方案。我的答案是很久以前写的,但我相信我提到的
arguments.callee.caller
是为了解决您在这里提出的问题well@james_womack
arguments.callee.caller
不总是可访问的(在我的nodejs应用程序中不是)。还有:但是我想在你写答案的时候用它是可以的:)明白你说的是有道理的
/**
 * 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;
    }
};