如何确定JavaScript中的当前行号?


Answers:


68

var thisline = new Error().lineNumber

如果在您使用的任何环境下都无法正常工作,则可以尝试:

var stack = new Error().stack

然后在堆栈中搜寻行号。


3
在IE中将无法使用,该lineNumber属性在错误对象上不存在。stack:-)都不这样做
Andy E

1
IE上某处有一个行号。我知道这是因为,当我的JavaScript抛出错误时,它说它处在一个大于1亿的数字上。
Malfist 2010年

我不完全得到正确的数字,其1350的时候应该是1250
Fzs2

1
问题:如果您使用的是PHP,则javascript看到的“源代码”不是原始源代码,因此它的行号错误。(这可能是Hermann发生的事情。)有人知道如何使javascript看到原始的PHP源代码行号吗?该解决方案可能涉及某种“源映射”生成,但是我找不到如何执行此操作。当然这是一个已解决的问题,对吗?
戴夫·伯顿

注意:有时候,构造Error对象时,堆栈/行号不可用,只有在抛出异常时才可用,例如在Google Apps脚本中-在这种情况下,请参阅此答案以获取解决方案。
user202729

37

您可以使用:

function test(){
    console.trace();
}

test();

1
到目前为止,最简单的解决方案甚至可以在MS Edge上运行。
危险

27

不同浏览器和浏览器版本之间的可移植性更高(应在Firefox,Chrome和IE10 +中运行):

function ln() {
  var e = new Error();
  if (!e.stack) try {
    // IE requires the Error to actually be throw 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/);
  // We want our caller's frame. It's index into |stack| depends on the
  // browser and browser version, so we need to search for the second frame:
  var frameRE = /:(\d+):(?:\d+)[^\d]*$/;
  do {
    var frame = stack.shift();
  } while (!frameRE.exec(frame) && stack.length);
  return frameRE.exec(stack.shift())[1];
}

谢谢。我将您的建议调整为:stackoverflow.com/a/37081135/470749
Ryan

1
如果您调整了正则表达式,则可以同时返回行号和列号:var frameRE = /:(\d+:\d+)[^\d]*$/;这很有用,尤其是当JS缩小为一条长行时。
Quinn Comendant

警告,在Chrome的ViolentMonkey脚本中不起作用-您会得到一个伪造的数字,不知道为什么。
hanshenrik '19

5

您可以尝试解析函数的源以查找一些标记。
这是一个简单的示例(是的,有点混乱了)。

function foo()  
{       
    alert(line(1));
    var a;
    var b;      
    alert(line(2));
}   
foo();

function line(mark)
{
    var token = 'line\\(' + mark + '\\)';       
    var m = line.caller.toString().match(
        new RegExp('(^(?!.*' + token + '))|(' + token + ')', 'gm')) || [];
    var i = 0;
    for (; i < m.length; i++) if (m[i]) break;
    return i + 1;
}

3

将以下代码段插入代码中:

console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);

根据需要替换协议名称(例如“ http:”)
crishushu 2014年

1
我无法使它正常工作。我懂了TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
瑞安

2

你可以试试:

window.onerror = handleError;
function handleError(err, url, line){
    alert(err + '\n on page: ' + url + '\n on line: ' + line);
}

然后在您想知道的地方抛出一个错误(不是很需要,但是如果您正在调试,则可能会有所帮助。

注意:window.onerror未在WebKitOpera中定义/处理(我上次检查)


1
请注意,window.onerror在webkit中不起作用:bugs.webkit.org/show_bug.cgi?id=8519
Annie

1
有趣。您甚至可以创建一个特殊的函数throwAndResume(resumeFunction);来存储resumeFunction,抛出错误,并在错误处理程序中记录详细信息,然后调用resumeFunction继续执行程序。
z5h 2010年


-2

如果您的代码是JavaScript + PHP,那么当前的PHP行号在JavaScript中可以作为文字常量使用,因为它在PHP中可以作为   <?= __LINE__ ?>

(显然,这是假设您已启用PHP短标签。)

因此,例如,在JavaScript中,您可以说:

this_php_line_number = <?= __LINE__ ?>;

但是,如果您不小心,PHP行号可能与JavaScript行号不同,因为PHP在浏览器看到源代码行之前就“吞噬”了源代码行。因此,问题就变成了确保您的PHP和JavaScript行号相同。如果它们不同,那么使用浏览器的JavaScript调试器将变得不那么愉快。

您可以通过包含一条PHP语句来确保行号相同,该PHP语句写入同步服务器端(PHP)和浏览器端(JavaScript)行号所需的正确换行数。

这是我的代码:

<!DOCTYPE html>
<html lang="en">
<!-- Copyright 2016, 2017, me and my web site -->
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, user-scalable=yes">

<?php

...lots of PHP stuff here, including all PHP function definitions ...

echo str_repeat("\n",__LINE__-6); # Synchronize PHP and JavaScript line numbers
?>
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

  <title>My web page title</title>

...lots of HTML and JavaScript stuff here...

</body>
</html>
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

关键是这个PHP语句:

echo str_repeat("\n",__LINE__-6);

这样会产生足够的换行符,以使JavaScript看到的行号与PHP的行号相同。所有PHP函数定义等都位于该行的顶部。

在该行之后,我将PHP的使用限制为不更改行号的代码。

“ -6”说明了我的PHP代码从第8行开始的事实。如果您较早启动PHP代码,则会减少该数量。有些人将他们的PHP放在最顶端,甚至领先于DOCTYPE。

(根据此堆栈溢出问答,meta视口行会禁用Android Chrome“字体增强”功能: Android上的Chrome会调整字体大小。考虑一下每个网页都需要的样板。)

以下行仅用于验证我没有记错。在浏览器的调试器中查看,或者通过右键单击/ save-web-page查看,它变为HTML注释,其中显示了正确的源文件名和行号:

<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->

变成:

<!-- *** this is line 1234 of my_file.php *** -->

现在,无论我在哪里看到行号,无论是在错误消息中还是在JavaScript调试器中,它都是正确的。PHP行号和JavaScript行号始终一致且相同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.