JavaScript ha un meccanismo per determinare il numero di riga dell'istruzione attualmente in esecuzione (e se sì, qual è)?
JavaScript ha un meccanismo per determinare il numero di riga dell'istruzione attualmente in esecuzione (e se sì, qual è)?
Risposte:
var thisline = new Error().lineNumber
Se ciò non funziona in qualunque ambiente tu stia utilizzando, puoi provare:
var stack = new Error().stack
Quindi cerca nello stack il numero di riga.
lineNumber
proprietà non esiste sugli oggetti di errore. Nemmeno stack
:-)
Un po 'più portabile tra diversi browser e versioni del browser (dovrebbe funzionare in Firefox, Chrome e 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]*$/;
che è molto più utile, in particolare quando JS è minimizzato in una riga lunga.
Puoi provare ad analizzare una fonte di una funzione per cercare alcuni contrassegni.
Ecco un rapido esempio (sì, è un po 'incasinato).
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;
}
Inserisci il seguente frammento di codice nel tuo codice:
console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
.
Puoi provare:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Quindi genera un errore dove vuoi sapere (non eccessivamente desiderato, ma potrebbe aiutarti se stai eseguendo il debug.
Nota: window.onerror
non è definito / gestito in WebKit o Opera (l'ultima volta che ho controllato)
throwAndResume(resumeFunction);
che memorizzi resumeFunction, generi l'errore e nel tuo gestore di errori registri i dettagli, quindi chiami resumeFunction per continuare il tuo programma.
Puramente non si può ottenere il numero di riga da Error.stack, perché in Angular il numero di riga è il numero di riga del codice compilato. Ma si possono ottenere informazioni su quale metodo è stato creato l'errore. Il registratore di classe in questo frammento di codice aggiunge questa informazione a una nuova voce del registro.
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
Se il tuo codice è JavaScript + PHP, il numero di riga PHP corrente è disponibile in JavaScript come costante letterale, perché è disponibile in PHP come <?= __LINE__ ?>
(Questo presuppone che tu abbia abilitato i tag brevi PHP, ovviamente.)
Quindi, ad esempio, in JavaScript puoi dire:
this_php_line_number = <?= __LINE__ ?>;
Tuttavia, se non stai attento, il numero di riga PHP potrebbe essere diverso dal numero di riga JavaScript, perché PHP "mangia" le righe sorgente prima che il browser le veda. Quindi il problema diventa garantire che i numeri di riga PHP e JavaScript siano gli stessi. Se sono diversi, l'utilizzo del debugger JavaScript del browser è molto meno piacevole.
Puoi assicurarti che i numeri di riga siano gli stessi includendo un'istruzione PHP che scrive il numero corretto di nuove righe necessarie per sincronizzare i numeri di riga lato server (PHP) e lato browser (JavaScript).
Ecco come appare il mio codice:
<!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__); ?> *** -->
La chiave è questa dichiarazione PHP:
echo str_repeat("\n",__LINE__-6);
Questo genera abbastanza nuove righe da rendere il numero di riga visto da JavaScript uguale al numero di riga PHP. Tutte le definizioni delle funzioni PHP, ecc. Sono in alto, prima di quella riga.
Dopo quella riga, limito il mio uso di PHP al codice che non modifica i numeri di riga.
Il "-6" spiega il fatto che il mio codice PHP inizia alla riga 8. Se avvii il tuo codice PHP prima, ridurrai quel numero. Alcune persone mettono il proprio PHP in cima, addirittura prima del DOCTYPE.
(La linea meta viewport disabilita il "potenziamento dei caratteri" di Android Chrome in base a questa domanda e risposta sull'overflow dello stack: Chrome su Android ridimensiona il carattere . Consideralo boilerplate, di cui ogni pagina web ha bisogno.)
La riga seguente serve solo per verificare che non ho commesso un errore. Visto nel debugger del browser, o facendo clic con il pulsante destro del mouse / salva-pagina web, diventa un commento HTML che mostra il nome del file sorgente corretto e il numero di riga:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
diventa:
<!-- *** this is line 1234 of my_file.php *** -->
Ora, ovunque vedo un numero di riga, sia che si trovi in un messaggio di errore o nel debugger JavaScript, è corretto. I numeri di riga PHP e i numeri di riga JavaScript sono sempre coerenti e identici.