115

JavaScript 是否有一种机制来确定当前正在执行的语句的行号(如果有,它是什么)?

4

8 回答 8

77

var thisline = new Error().lineNumber

如果这在您使用的任何环境中都不起作用,您可以尝试:

var stack = new Error().stack

然后在堆栈中寻找行号。

于 2010-02-26T17:08:48.000 回答
49

您可以使用:

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

test();
于 2015-04-16T01:57:03.577 回答
28

在不同的浏览器和浏览器版本之间更具可移植性(应该在 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];
}
于 2014-11-22T04:58:20.217 回答
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;
}
于 2010-02-26T19:01:30.820 回答
3

将以下代码段注入您的代码:

console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
于 2014-03-07T15:36:29.330 回答
1

你可以试试:

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

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

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

于 2010-02-26T18:22:27.177 回答
-1

纯粹无法从 Error.stack 中获取行号,因为在 Angular 中,行号是编译代码的行号。但是可以获取错误是在哪种方法中创建的信息。此代码片段中的 Logger 类将此信息添加到新的日志条目中。

https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts

于 2020-04-02T13:52:50.743 回答
-2

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

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

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

this_php_line_number = <?= __LINE__ ?>;

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

您可以通过包含一个 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 viewport 行根据 Stack Overflow Q&A 禁用 Android Chrome“字体提升”:Android 上的 Chrome 调整字体大小。考虑它是每个网页都需要的样板。)

以下行仅用于验证我没有犯错。在浏览器的调试器中查看,或通过右键单击/保存网页,它变成一个 HTML 注释,显示正确的源文件名和行号:

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

变成:

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

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

于 2017-01-26T15:15:14.073 回答