O JavaScript tem um mecanismo para determinar o número da linha da instrução em execução no momento (e, em caso afirmativo, qual é)?
O JavaScript tem um mecanismo para determinar o número da linha da instrução em execução no momento (e, em caso afirmativo, qual é)?
Respostas:
var thisline = new Error().lineNumber
Se isso não funcionar em qualquer ambiente que estiver usando, você pode tentar:
var stack = new Error().stack
Em seguida, procure na pilha o número da linha.
lineNumber
propriedade não existe em objetos de erro. Nem stack
:-)
Um pouco mais portátil entre diferentes navegadores e versões de navegador (deve funcionar no 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]*$/;
que é muito mais útil, principalmente quando o JS é reduzido em uma linha longa.
Você pode tentar analisar a origem de uma função para buscar algumas marcas.
Aqui está um exemplo rápido (sim, está um pouco confuso).
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;
}
Injete o seguinte snippet em seu código:
console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
.
Podes tentar:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Em seguida, lance um erro onde você deseja saber (não muito desejado, mas pode ajudá-lo se você estiver depurando.
Nota: window.onerror
não é definido / tratado no WebKit ou Opera (a última vez que verifiquei)
throwAndResume(resumeFunction);
que armazenaria resumeFunction, geraria o erro e, em seu log do manipulador de erros, os detalhes e chamaria resumeFunction para continuar seu programa.
Simplesmente não se pode obter o número da linha de Error.stack, porque no Angular o número da linha é o número da linha do código compilado. Mas pode-se obter a informação de qual método o erro foi criado. A classe Logger neste trecho de código adiciona esta informação a uma nova entrada do logbook.
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
Se seu código for JavaScript + PHP, o número da linha atual do PHP está disponível em JavaScript como uma constante literal, porque está disponível em PHP como <?= __LINE__ ?>
(Isso presumindo que você tenha tags curtas do PHP ativadas, obviamente.)
Então, por exemplo, em JavaScript, você pode dizer:
this_php_line_number = <?= __LINE__ ?>;
No entanto, se você não for cuidadoso, o número da linha do PHP pode ser diferente do número da linha do JavaScript, porque o PHP "come" as linhas de origem antes que o navegador as veja. Portanto, o problema passa a ser garantir que os números de linha do PHP e do JavaScript sejam iguais. Se forem diferentes, o uso do depurador de JavaScript do navegador será muito menos agradável.
Você pode garantir que os números das linhas sejam os mesmos incluindo uma instrução PHP que grava o número correto de novas linhas necessárias para sincronizar os números de linha do lado do servidor (PHP) e do lado do navegador (JavaScript).
Aqui está a aparência do meu código:
<!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__); ?> *** -->
A chave é esta declaração PHP:
echo str_repeat("\n",__LINE__-6);
Isso gera novas linhas suficientes para fazer o número da linha visto pelo JavaScript ser igual ao número da linha do PHP. Todas as definições de função PHP, etc. estão no topo, à frente dessa linha.
Depois dessa linha, eu restrinjo meu uso de PHP a código que não altera os números das linhas.
O "-6" explica o fato de que meu código PHP começa na linha 8. Se você iniciar seu código PHP antes, reduzirá esse número. Algumas pessoas colocam seu PHP bem no topo, até mesmo à frente do DOCTYPE.
(A linha da janela de visualização meta desativa o "aumento de fonte" do Android Chrome de acordo com as perguntas e respostas do Stack Overflow: o Chrome no Android redimensiona a fonte . Considere-o padrão, que toda página da web precisa.
A linha a seguir serve apenas para verificar se não cometi um erro. Visualizado no depurador do navegador ou clicando com o botão direito / salvar página da web, torna-se um comentário HTML que mostra o nome do arquivo de origem correto e o número da linha:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
torna-se:
<!-- *** this is line 1234 of my_file.php *** -->
Agora, sempre que vejo um número de linha, seja em uma mensagem de erro ou no depurador de JavaScript, está correto. Os números das linhas PHP e JavaScript são sempre consistentes e idênticos.