Есть ли в JavaScript механизм для определения номера строки выполняемого в данный момент оператора (и если да, то какой)?
Есть ли в JavaScript механизм для определения номера строки выполняемого в данный момент оператора (и если да, то какой)?
Ответы:
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;
}
Можешь попробовать:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Затем выдайте ошибку там, где вы хотите знать (не слишком желательно, но это может помочь вам, если вы отлаживаете.
Примечание: window.onerror
не определяется / не обрабатывается в WebKit или Opera (в последний раз, когда я проверял)
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) и на стороне браузера (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.
(Строка мета-области просмотра отключает «усиление шрифта» Android Chrome в соответствии с этими вопросами и ответами по переполнению стека: Chrome на Android изменяет размер шрифта . Считайте это шаблоном, который нужен каждой веб-странице.)
Следующая строка предназначена только для проверки того, что я не ошибся. При просмотре в отладчике браузера или при щелчке правой кнопкой мыши / сохранении веб-страницы он становится комментарием HTML, который показывает правильное имя исходного файла и номер строки:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
становится:
<!-- *** this is line 1234 of my_file.php *** -->
Теперь, когда я вижу номер строки, будь то сообщение об ошибке или отладчик JavaScript, он правильный. Номера строк PHP и номера строк JavaScript всегда согласованы и идентичны.