Czy JavaScript ma mechanizm określania numeru wiersza aktualnie wykonywanej instrukcji (a jeśli tak, to co to jest)?
Czy JavaScript ma mechanizm określania numeru wiersza aktualnie wykonywanej instrukcji (a jeśli tak, to co to jest)?
Odpowiedzi:
var thisline = new Error().lineNumber
Jeśli to nie zadziała w jakimkolwiek środowisku, z którego korzystasz, możesz spróbować:
var stack = new Error().stack
Następnie przeszukaj stos w poszukiwaniu numeru linii.
lineNumber
właściwość nie istnieje na obiektach błędów. Ani stack
:-)
Nieco bardziej przenośny między różnymi przeglądarkami i wersjami przeglądarek (powinien działać w Firefox, Chrome i 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]*$/;
co jest znacznie bardziej przydatne, szczególnie gdy JS jest zminimalizowany do jednej długiej linii.
Możesz spróbować przeanalizować źródło funkcji, aby wyszukać jakieś znaczniki.
Oto krótki przykład (tak, jest trochę pomieszany).
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;
}
Wstaw następujący fragment kodu do swojego kodu:
console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
.
Możesz spróbować:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Następnie wyślij błąd tam, gdzie chcesz wiedzieć (niezbyt pożądane, ale może ci pomóc, jeśli debugujesz.
Uwaga: window.onerror
nie jest zdefiniowany / obsługiwany w WebKit lub Opera (ostatni raz sprawdzałem)
throwAndResume(resumeFunction);
która będzie przechowywać resumeFunction, zgłaszać błąd, aw dzienniku obsługi błędów szczegóły, a następnie wywołać resumeFunction, aby kontynuować program.
Po prostu nie można pobrać numeru linii ze stosu Error.stack, ponieważ w Angular numer linii jest numerem linii skompilowanego kodu. Ale można uzyskać informację, w której metodzie został utworzony błąd. Klasa Logger w tym fragmencie kodu dodaje tę informację do nowego wpisu dziennika.
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
Jeśli twój kod to JavaScript + PHP, to bieżący numer linii PHP jest dostępny w JavaScript jako stała dosłowna, ponieważ jest dostępny w PHP jako <?= __LINE__ ?>
(Oczywiście zakładając, że masz włączone krótkie tagi PHP).
Na przykład w JavaScript możesz powiedzieć:
this_php_line_number = <?= __LINE__ ?>;
Jednakże, jeśli nie jesteś ostrożny, numer linii PHP może różnić się od numeru linii JavaScript, ponieważ PHP „zjada” linie źródłowe, zanim przeglądarka kiedykolwiek je zobaczy. Problem polega więc na upewnieniu się, że numery linii w PHP i JavaScript są takie same. Jeśli są różne, korzystanie z debugera JavaScript przeglądarki jest o wiele mniej przyjemne.
Możesz upewnić się, że numery wierszy są takie same, dołączając instrukcję PHP, która zapisuje poprawną liczbę nowych wierszy potrzebną do synchronizacji numerów wierszy po stronie serwera (PHP) i przeglądarki (JavaScript).
Oto jak wygląda mój kod:
<!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__); ?> *** -->
Kluczem jest ta instrukcja PHP:
echo str_repeat("\n",__LINE__-6);
To wypluwa wystarczająco dużo nowych linii, aby numer linii widziany przez JavaScript był taki sam, jak numer linii PHP. Wszystkie definicje funkcji PHP itp. Znajdują się na górze, przed tą linią.
Po tej linii ograniczam używanie PHP do kodu, który nie zmienia numerów linii.
Wartość „-6” odpowiada za to, że mój kod PHP zaczyna się w linii 8. Jeśli uruchomisz kod PHP wcześniej, zmniejszysz tę liczbę. Niektórzy ludzie umieszczają PHP na samym szczycie, nawet przed DOCTYPE.
(Linia meta viewport wyłącza „zwiększanie czcionek” w Androidzie Chrome zgodnie z tym pytaniem i odpowiedziami w przypadku przepełnienia stosu: Chrome na Androida zmienia rozmiar czcionki . Rozważ to szablon, którego potrzebuje każda strona internetowa).
Poniższy wiersz służy tylko do sprawdzenia, czy nie popełniłem błędu. Wyświetlany w debugerze przeglądarki lub po kliknięciu prawym przyciskiem myszy / zapisaniu strony internetowej, staje się komentarzem HTML, który pokazuje poprawną nazwę pliku źródłowego i numer wiersza:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
staje się:
<!-- *** this is line 1234 of my_file.php *** -->
Teraz, gdziekolwiek widzę numer linii, czy to w komunikacie o błędzie, czy w debugerze JavaScript, jest poprawny. Numery linii PHP i numery linii JavaScript są zawsze spójne i identyczne.