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

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

79623 次浏览

var thisline = new Error().lineNumber

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

var stack = new Error().stack

然后在堆栈中搜索行号。

你可以试试:

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

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

注意: window.onerrorWebKit歌剧中没有定义/处理(我上次检查的时候)

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

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

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

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

在不同浏览器和浏览器版本之间更加便携(应该可以在 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];
}

你可使用:

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


test();

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

(当然,前提是您启用了 PHP 短标记。)

So, for example, in JavaScript you can say:

this_php_line_number = <?= __LINE__ ?>;

However, if you are not careful, the PHP line number might be different from the JavaScript line number, because PHP "eats" source lines before the browser ever sees them. So the problem becomes ensuring that your PHP and JavaScript line numbers are the same. If they're different it makes using the browser's JavaScript debugger a lot less pleasant.

可以通过包含一个 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: Chrome 在 Android 上调整字体大小禁用 Android Chrome 的“字体增强”功能。考虑一下它的样板,每个网页都需要它。)

下面这行只是为了验证我没有犯错误。在浏览器的调试器中,或通过右键单击/保存网页,它变成一个 HTML 注释,显示正确的源文件名和行号:

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

变成:

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

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

纯粹地说,我们不能从 Error.stack 中得到行号,因为在 Angular 中,行号是已编译代码的行号。但是我们可以得到在哪个方法中创建错误的信息。此代码片段中的 Logger 类将此信息添加到新的日志记录条目中。

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

const line = new Error().stack.match(/(:[\d]+)/)[0].replace(':','')
console.log(line)