Wie kann ich die aktuelle Zeilennummer in JavaScript ermitteln?

Antworten:

67

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.

z5h
quelle
3
Funktioniert nicht im IE, die lineNumberEigenschaft ist für Fehlerobjekte nicht vorhanden. Auch nicht stack:-)
Andy E
1
Irgendwo im IE gibt es eine Zeilennummer. Ich weiß das, weil wenn mein Javascript einen Fehler auslöst, dies in einer Zeile mit einer Zahl von mehr als 100 Millionen steht.
Malfist
Ich bekomme nicht ganz die richtige Zahl, es ist 1350, wenn es 1250 sein sollte.
Fzs2
1
Problem: Wenn Sie PHP verwenden, ist der von Javascript angezeigte "Quellcode" nicht der ursprüngliche Quellcode, daher hat er die falschen Zeilennummern. (Das passiert wahrscheinlich mit Hermann.) Weiß jemand, wie man Javascript dazu bringt, die ursprünglichen PHP-Quellcode-Zeilennummern zu sehen? Die Lösung beinhaltet wahrscheinlich eine Art "Quellkarten" -Erstellung, aber ich kann nicht finden, wie das geht. Sicher ist das ein gelöstes Problem, oder?
Dave Burton
Hinweis: Manchmal ist die Stapel- / Zeilennummer nicht verfügbar, wenn das Fehlerobjekt erstellt wird, sondern nur, wenn es ausgelöst wird, z. B. in Google Apps Script. In diesem Fall finden Sie in dieser Antwort die Lösung.
user202729
35

Sie können verwenden:

function test(){
    console.trace();
}

test();
Baligena
quelle
1
Bei weitem die einfachste Lösung und es funktioniert sogar auf MS Edge.
Gefahr
27

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];
}
jwatt
quelle
Vielen Dank. Ich habe Ihren Vorschlag daran angepasst: stackoverflow.com/a/37081135/470749
Ryan
1
Wenn Sie den 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.
Quinn Comendant
Warnung, funktioniert nicht in ViolentMonkey-Skripten für Chrome - Sie erhalten eine falsche Nummer, wissen nicht warum.
Hanshenrik
5

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;
}
Mikhail Nasyrov
quelle
3

Fügen Sie Ihrem Code das folgende Snippet hinzu:

console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
Crishushu
quelle
Ersetzen Sie den Protokollnamen nach Bedarf (z. B. "http:")
Crishushu
1
Ich konnte das nicht zum Laufen bringen. Ich verstehe TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null.
Ryan
2

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.onerrorWird in WebKit oder Opera nicht definiert / verarbeitet (das letzte Mal, als ich es überprüft habe).

scunliffe
quelle
1
Beachten Sie, dass window.onerror im Webkit nicht funktioniert: bugs.webkit.org/show_bug.cgi?id=8519
Annie
1
Interessant. Sie können sogar eine spezielle Funktion erstellen 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.
z5h
0

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

Viree
quelle
-1

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.

Dave Burton
quelle