如何获取 JavaScript 调用者函数行号和调用者源 URL

IT技术 javascript
2021-01-29 01:51:28

我正在使用以下内容来获取 JavaScript 调用函数名称:

var callerFunc = arguments.callee.caller.toString();
callerFuncName = (callerFunc.substring(callerFunc.indexOf("function") + 8, callerFunc.indexOf("(")) || "anoynmous")

有没有办法发现调用该方法的行号?

另外,有没有办法获取调用该方法的 JavaScript 文件的名称?还是源网址?

6个回答

这在 chrome/QtWebView 中对我有用

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();
var caller_line = err.stack.split("\n")[4];
var index = caller_line.indexOf("at ");
var clean = caller_line.slice(index+2, caller_line.length);
也可以在 PhantomJS 中使用,但是您必须抛出它,否则不会在错误上设置“stack”属性。
2021-03-18 01:51:28
将此建议与另一个类似的答案合并以获得 FF/Webkit“标准化”响应——参见stackoverflow.com/a/14841411/1037948
2021-03-30 01:51:28
不需要抛出错误;简单地创建它就足够了:var caller_line = (new Error).stack.split("\n")[4]
2021-04-02 01:51:28
也适用于节点。在您的自定义 log() 函数中弹出它(它添加了您需要的任何其他有用的解决方法 - 例如修复了 Chrome 数组日志记录)并且仍然是您调用 log() 的任何地方的行号。
2021-04-03 01:51:28
@ELLIOTTCABLE 实际上在某些浏览器(例如 iOS Safari)中,您确实需要抛出异常!那么为什么不这样做呢?
2021-04-06 01:51:28

kangax 的解决方案引入了不必要的 try..catch 范围。如果您需要访问 JavaScript 中某些内容的行号(只要您使用的是 Firefox 或 Opera),只需访问(new Error).lineNumber.

您好,感谢您的插件。你知道是否有可能从以前的电话中获得行号吗?假设方法 A 调用 B ,现在在 BI 中想知道调用是在 A 下的哪一行进行的?
2021-03-14 01:51:28
而且,这是极其有限的。最好的解决方案是抛出错误并在所有现代浏览器中都可用的 error.stack 上使用正则表达式。您可以轻松提取该路径、文件、行和列。没问题。
2021-03-19 01:51:28
这是勾选的,但没有回答问题,即如何获取调用者函数的行号
2021-04-10 01:51:28

我很惊讶这些答案中的大多数都假设您想要处理错误,而不仅仅是为正常情况输出有用的调试跟踪。

例如,我喜欢使用这样的console.log包装器:

consoleLog = function(msg) {//See https://stackoverflow.com/a/27074218/470749
    var e = new Error();
    if (!e.stack) {
        try {
            // IE requires the Error to actually be thrown or else the 
            // Error's 'stack' property is undefined.
            throw e;
        } catch (e) {
            if (!e.stack) {
                //return 0; // IE < 10, likely
            }
        }
    }
    var stack = e.stack.toString().split(/\r\n|\n/);
    if (msg === '') {
        msg = '""';
    }
    console.log(msg, '          [' + stack[1] + ']');        
}

这最终会在我的控制台上打印如下输出:

1462567104174 [getAllPosts@http://me.com/helper.js:362:9]

请参阅https://stackoverflow.com/a/27074218/以及具有正确行号的 console.log 的适当包装器?

适用于 firefox 浏览器,但不适用于 node.js。
2021-03-14 01:51:28
在节点下你必须记录堆栈[2]
2021-03-24 01:51:28
有没有人测试过这段代码,看看它是否有效?if 条件的if (!e.stack)范围是什么?这看起来像是一个python程序员的指纹;-)
2021-03-30 01:51:28
@puk 我从不喜欢 Python,但正如我在上面的代码注释中提到的,我是从stackoverflow.com/a/27074218/470749得到的,我不能说那个人是否喜欢 Python。但是,是的,这段代码在 2016 年对我有用。不过我已经好几年没有使用它了。stackoverflow.com/a/55392553/470749看起来很有趣。
2021-04-04 01:51:28
@Ryan 我认为解析如下:if (!e.stack)try{...}并且catch{...}只是悬空。任何专业的 js 人都想解析上面的代码?我是一个 C 人,所以对我来说这应该会抛出一个悬空catch语句的错误
2021-04-10 01:51:28

我意识到这是一个老问题,但现在有一个方法被调用console.trace("Message"),它将向您显示行号和导致日志的方法调用链以及您传递的消息。有关 javascript 日志记录技巧的更多信息,请访问freecodecamp这篇中等博客文章

这通常是通过从当前上下文中抛出错误来实现的;然后分析像lineNumberfileName这样的属性的错误对象(某些浏览器具有)

function getErrorObject(){
  try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();

err.fileName;
err.lineNumber; // or `err.line` in WebKit

不要忘记该callee.caller属性已被弃用(并且从未真正出现在 ECMA 第 3 版中。首先)。

还要记住,函数反编译被指定为依赖于实现,因此可能会产生非常意外的结果。在这里这里写过它

@Elijah 这就是我在 FF3 中看到的。另一方面,WebKitline仅在抛出错误时填充
2021-03-12 01:51:28
callee.caller 的替代品是什么?如果我需要获取函数名称?
2021-03-21 01:51:28
谢谢,在我需要的应用程序中添加这段代码似乎有点问题。(一些 js 跟踪框架)你知道我可以使用的任何其他未被弃用的方法吗?
2021-03-22 01:51:28
您应该能够在不依赖于 deprecated 的情况下检查错误对象callee.caller
2021-03-29 01:51:28
你不需要抛出错误。您只需使用 (new Error).lineNumber 来访问脚本中的当前行号。
2021-04-11 01:51:28