Чи має 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 відповідно до цього запитання та відповіді Stack Overflow: Chrome на Android змінює розмір шрифту . Розгляньте його як шаблон, який потрібен кожній веб-сторінці.)
Наступний рядок призначений лише для підтвердження того, що я не помилився. Переглядаючись у налагоджувачі браузера або клацнувши правою кнопкою миші / збереження веб-сторінки, він стає коментарем HTML, який показує правильне ім'я вихідного файлу та номер рядка:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
стає:
<!-- *** this is line 1234 of my_file.php *** -->
Тепер, де б я не бачив номер рядка, будь то в повідомленні про помилку або в налагоджувачі JavaScript, це правильно. Номери рядків PHP та номери рядків JavaScript завжди узгоджені та однакові.