JavaScript是否具有确定当前正在执行的语句的行号的机制(如果是,它是什么)?
JavaScript是否具有确定当前正在执行的语句的行号的机制(如果是,它是什么)?
Answers:
var thisline = new Error().lineNumber
如果在您使用的任何环境下都无法正常工作,则可以尝试:
var stack = new Error().stack
然后在堆栈中搜寻行号。
lineNumber
属性在错误对象上不存在。stack
:-)都不这样做
不同浏览器和浏览器版本之间的可移植性更高(应在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];
}
var frameRE = /:(\d+:\d+)[^\d]*$/;
这很有用,尤其是当JS缩小为一条长行时。
您可以尝试解析函数的源以查找一些标记。
这是一个简单的示例(是的,有点混乱了)。
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]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
。
throwAndResume(resumeFunction);
来存储resumeFunction,抛出错误,并在错误处理程序中记录详细信息,然后调用resumeFunction继续执行程序。
纯粹无法从Error.stack中获取行号,因为在Angular中,行号是已编译代码的行号。但是,可以获取使用哪种方法创建错误的信息。此代码段中的Logger类将这些信息添加到新的日志条目中。
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
如果您的代码是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行号始终一致且相同。