Javascript 获取node.js中调用函数的名称和行

Javascript 获取node.js中调用函数的名称和行,javascript,node.js,Javascript,Node.js,如何获取调用当前函数的函数的名称和行?我希望有这样一个基本的调试功能(通过定义log.debug): 当从另一个函数调用时,它将如下所示: function hello() { debug("world!") } // outputs something like: // "hello:2 'world!'" 为清楚起见,我想要的基本上类似于: 是否有一个相当于完成此任务的节点?我找到并安装了模块(与npm安装堆栈跟踪一起安装),然后将echo定义为: function echo() {

如何获取调用当前函数的函数的名称和行?我希望有这样一个基本的调试功能(通过定义
log.debug
):

当从另一个函数调用时,它将如下所示:

function hello() {
   debug("world!")
}
// outputs something like:
// "hello:2 'world!'"
为清楚起见,我想要的基本上类似于:

是否有一个相当于完成此任务的节点?

我找到并安装了模块(与
npm安装堆栈跟踪一起安装),然后将
echo
定义为:

function echo() {
  var args, file, frame, line, method;
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];

  frame = stackTrace.get()[1];
  file = path.basename(frame.getFileName());
  line = frame.getLineNumber();
  method = frame.getFunctionName();

  args.unshift("" + file + ":" + line + " in " + method + "()");
  return log.info.apply(log, args); // changed 'debug' to canonical npmlog 'info'
};
函数echo(){
变量参数、文件、帧、行、方法;
args=1使用此处的信息:

您可以添加一些原型,以便从V8中访问此信息:

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();
    }
});

Object.defineProperty(global, '__function', {
get: function() {
        return __stack[1].getFunctionName();
    }
});

function foo() {
    console.log(__line);
    console.log(__function);
}

foo()

分别返回'28'和'foo'。

我也有类似的要求。我使用了nodejs提供的错误类的堆栈属性。
我仍在学习节点,因此可能会出错。

下面是相同的解释。也为相同的创建了npm模块,如果您愿意,您可以访问:
1.
二,

假设我们使用方法“log”创建“logger”对象

var logger = {
 log: log
}
function log(msg){
  let logLineDetails = ((new Error().stack).split("at ")[3]).trim();
  console.log('DEBUG', new Date().toUTCString(), logLineDetails, msg);
}
示例:

//suppose file name: /home/vikash/example/age.js
function getAge(age) {
    logger.log('Inside getAge function');    //suppose line no: 9
}
    DEBUG on Sat, 24 Sept 2016 12:12:10 GMT at getAge(/home/vikash/example/age.js:9:12)
    Inside getAge function
以上示例的输出:

//suppose file name: /home/vikash/example/age.js
function getAge(age) {
    logger.log('Inside getAge function');    //suppose line no: 9
}
    DEBUG on Sat, 24 Sept 2016 12:12:10 GMT at getAge(/home/vikash/example/age.js:9:12)
    Inside getAge function

以下代码仅使用核心元素。它从错误实例解析堆栈

"use strict";
function debugLine(message) {
    let e = new Error();
    let frame = e.stack.split("\n")[2]; // change to 3 for grandparent func
    let lineNumber = frame.split(":").reverse()[1];
    let functionName = frame.split(" ")[5];
    return functionName + ":" + lineNumber + " " + message;
}
function myCallingFunction() {
    console.log(debugLine("error_message"));
}
myCallingFunction();
它输出类似于
myCallingFunction:10错误\u消息的内容

我已将错误元素提取为变量(lineNumber、functionName),因此您可以按任何方式格式化返回值


作为旁注:
use strict;
语句是可选的,仅当您的整个代码都在使用标准时才可以使用。如果您的代码与标准不兼容(虽然应该兼容),则可以随意删除它。

这里有一个用于快速调试的单行程序:

console.log(“调试”),(新错误().stack.split(“at”)[1]).trim());
这将在Node.js中记录类似的内容:

DEBUG SomeObject.function (/path/to/the/code.js:152:37)
请注意,如果将其放入helper函数中,请将堆栈索引从例如
[1]
调整为
[2]

以下是一种在发生错误时获取文件名的方法。您必须将函数包装在onErrorReturnFileName中。这里我将从
其他节点
文件中包装
func()

const {func} = require('./otherNode')

function onErrorReturnFileName(funcToRead) {
    let defaultPrepareStackTrace = Error.prepareStackTrace
    try {
        let getStack = function (err, stack) { return stack; };
        Error.prepareStackTrace = getStack
        return {result: funcToRead(), name: null}
    }catch (ex) {
        return {naem: ex.stack.shift().getFileName(), result: null}
    }
    Error.preppareStackTrace = defaultPrepareStackTrace
}
console.log(onErrorReturnFileName(func))

这可能是有用的,我问了一个类似的问题,但与节点无关:谢谢Joe。也许
\uuuu行
\uu函数
可能更适合命名为
\uu父行
\uu父函数名
,但除此之外这很好(顺便说一句,
堆栈跟踪
在我的回答中是如何工作的)。他们使用第二帧,否则您只需获取有关_行和_函数的信息。:)有关
堆栈跟踪的有趣信息必须检查。虽然此解决方案很好,但成本很高。我不会在生产代码中使用它。如果您使用bunyan logger,您可以打开。但是,他们也不建议在生产代码中使用此选项。我想要一个transpiler,它可以在我运行代码之前用函数名和行号的信息替换每个记录器调用。任何人??Vibgy,如果你使用的是TypeScript,你可以编写自己的自定义转换器来完成这项工作。请注意,如果你使用的是严格模式,由于
aguments.callee
t,此方法将无法工作他的很好,对于其他人来说,将上面的行更改为:args=1谢谢,我正在运行Tianium并获得了这个函数来记录消息的来源:
function log(msg){stackTrace=require(“stack trace/lib/stack trace”);var thistrace=stackTrace.get();var parent_name=thistrace[1].getFunctionName();var parent_eval=thistrace[1]。getEvalOrigin();msg=sprintf(“[%s][%s]:%s”,parent_eval,parent_name,msg);Ti.API.info(msg);}
太好了,它在重试时给出了错误的位置,不需要额外的依赖项。同意。这是一个很好的小解决方案。我只是注意到很难找到调用它的函数。假设您正在创建一个日志模块,那么拆分模式将从“at”更改为“\n”,行的顺序也会改变是的。现在进一步想象一下使用try-catch块。这变得更加困难。行号将在Windows上给出不同的结果,因为
C:/…
path。更好的方法可能是从分号分割结果向后工作。不过这是非常聪明的解决方案。谢谢!我修改了代码,使其与Windows兼容。sear行号的ch现在从错误行的末尾开始(数组在获取行值之前是反转的)。您好,我想您在catch scope(naem!=name)上写了一个拼写错误。我试图修复它,但不允许编辑小于6个符号的任何内容。