Verfügt JavaScript über einen Mechanismus zum Bestimmen der Zeilennummer der aktuell ausgeführten Anweisung (und wenn ja, um welche handelt es sich)?
Verfügt JavaScript über einen Mechanismus zum Bestimmen der Zeilennummer der aktuell ausgeführten Anweisung (und wenn ja, um welche handelt es sich)?
Antworten:
var thisline = new Error().lineNumber
Wenn dies in der von Ihnen verwendeten Umgebung nicht funktioniert, können Sie Folgendes versuchen:
var stack = new Error().stack
Suchen Sie dann im Stapel nach der Zeilennummer.
lineNumber
Eigenschaft ist für Fehlerobjekte nicht vorhanden. Auch nicht stack
:-)
Etwas portabler zwischen verschiedenen Browsern und Browserversionen (sollte in Firefox, Chrome und IE10 + funktionieren):
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]*$/;
regulären Ausdruck anpassen, können Sie sowohl Zeilen- als auch Spaltennummern zurückgeben. Dies ist viel nützlicher, insbesondere wenn das JS in eine lange Zeile verkleinert wird.
Sie können versuchen, eine Quelle einer Funktion zu analysieren, um nach Markierungen zu suchen.
Hier ist ein kurzes Beispiel (ja, es ist ein wenig durcheinander).
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;
}
Fügen Sie Ihrem Code das folgende Snippet hinzu:
console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
.
Du kannst es versuchen:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Geben Sie dann einen Fehler aus, den Sie wissen möchten (nicht übermäßig erwünscht, aber er kann Ihnen beim Debuggen helfen.
Hinweis: window.onerror
Wird in WebKit oder Opera nicht definiert / verarbeitet (das letzte Mal, als ich es überprüft habe).
throwAndResume(resumeFunction);
, die resumeFunction speichert, den Fehler auslöst und in Ihrem Fehlerbehandlungsprotokoll die Details protokolliert. Anschließend können Sie resumeFunction aufrufen, um Ihr Programm fortzusetzen.
Rein kann man die Zeilennummer nicht aus Error.stack herausholen, da in Angular die Zeilennummer die Zeilennummer des kompilierten Codes ist. Man kann aber die Information bekommen, in welcher Methode der Fehler erzeugt wurde. Die Klasse Logger in diesem Codefragment fügt diese Information einem neuen Logbucheintrag hinzu.
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
Wenn Ihr Code JavaScript + PHP ist, ist die aktuelle PHP-Zeilennummer in JavaScript als Literalkonstante verfügbar, da sie in PHP als verfügbar ist <?= __LINE__ ?>
(Dies setzt natürlich voraus, dass Sie PHP-Kurztags aktiviert haben.)
So können Sie beispielsweise in JavaScript sagen:
this_php_line_number = <?= __LINE__ ?>;
Wenn Sie jedoch nicht aufpassen, unterscheidet sich die PHP-Zeilennummer möglicherweise von der JavaScript-Zeilennummer, da PHP Quellzeilen "frisst", bevor der Browser sie jemals sieht. Das Problem besteht also darin, sicherzustellen, dass Ihre PHP- und JavaScript-Zeilennummern identisch sind. Wenn sie unterschiedlich sind, ist die Verwendung des JavaScript-Debuggers des Browsers weniger angenehm.
Sie können sicherstellen, dass die Zeilennummern identisch sind, indem Sie eine PHP-Anweisung einfügen, die die richtige Anzahl von Zeilenumbrüchen schreibt, die zum Synchronisieren der Zeilennummern auf der Serverseite (PHP) und auf der Browserseite (JavaScript) erforderlich sind.
So sieht mein Code aus:
<!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__); ?> *** -->
Der Schlüssel ist diese PHP-Anweisung:
echo str_repeat("\n",__LINE__-6);
Das spuckt genug Zeilenumbrüche aus, damit die von JavaScript angezeigte Zeilennummer mit der PHP-Zeilennummer übereinstimmt. Alle PHP-Funktionsdefinitionen usw. befinden sich oben vor dieser Zeile.
Nach dieser Zeile beschränke ich meine Verwendung von PHP auf Code, der die Zeilennummern nicht ändert.
Das "-6" berücksichtigt die Tatsache, dass mein PHP-Code in Zeile 8 beginnt. Wenn Sie Ihren PHP-Code früher starten, reduzieren Sie diese Anzahl. Einige Leute setzen ihr PHP ganz oben, sogar vor dem DOCTYPE.
(Die Meta-Ansichtsfensterzeile deaktiviert die "Erhöhung der Schriftart" für Android Chrome gemäß diesen Fragen und Antworten zum Stapelüberlauf : Chrome unter Android ändert die Schriftgröße . Betrachten Sie es als Boilerplate, das jede Webseite benötigt.)
Die folgende Zeile dient nur zur Überprüfung, ob ich einen Fehler gemacht habe. Wird im Debugger des Browsers oder durch Klicken mit der rechten Maustaste / Speichern der Webseite angezeigt, wird es zu einem HTML-Kommentar, der den korrekten Namen und die Zeilennummer der Quelldatei anzeigt:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
wird:
<!-- *** this is line 1234 of my_file.php *** -->
Wo immer ich eine Zeilennummer sehe, sei es in einer Fehlermeldung oder im JavaScript-Debugger, ist sie korrekt. PHP-Zeilennummern und JavaScript-Zeilennummern sind immer konsistent und identisch.