¿Tiene JavaScript un mecanismo para determinar el número de línea de la declaración que se está ejecutando actualmente (y si es así, cuál es)?
¿Tiene JavaScript un mecanismo para determinar el número de línea de la declaración que se está ejecutando actualmente (y si es así, cuál es)?
Respuestas:
var thisline = new Error().lineNumber
Si eso no funciona en el entorno que esté utilizando, puede intentar:
var stack = new Error().stack
Luego busque en la pila el número de línea.
lineNumber
propiedad no existe en los objetos de error. Tampoco stack
:-)
Un poco más portátil entre diferentes navegadores y versiones de navegador (debería funcionar en 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]*$/;
cual es mucho más útil, especialmente cuando el JS se reduce a una línea larga.
Puede intentar analizar una fuente de una función para buscar algunas marcas.
Aquí hay un ejemplo rápido (sí, está un poco desordenado).
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;
}
Inyecta el siguiente fragmento de código a tu código:
console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null
.
Puedes probar:
window.onerror = handleError;
function handleError(err, url, line){
alert(err + '\n on page: ' + url + '\n on line: ' + line);
}
Luego, arroje un error donde quiera saber (no demasiado deseado, pero podría ayudarlo si está depurando.
Nota: window.onerror
no está definido / manejado en WebKit u Opera (la última vez que verifiqué)
throwAndResume(resumeFunction);
que almacene resumeFunction, arroje el error y, en su controlador de errores, registre los detalles y luego llame a resumeFunction para continuar su programa.
Simplemente, no se puede obtener el número de línea de Error.stack, porque en Angular el número de línea es el número de línea del código compilado. Pero uno puede obtener la información en qué método se creó el error. La clase Logger en este fragmento de código agrega esta información a una nueva entrada del libro de registro.
https://stackblitz.com/edit/angular-logger?file=src/app/Logger/logger.ts
Si su código es JavaScript + PHP, entonces el número de línea PHP actual está disponible en JavaScript como una constante literal, porque está disponible en PHP como <?= __LINE__ ?>
(Eso es asumiendo que tiene habilitadas las etiquetas cortas de PHP, obviamente).
Entonces, por ejemplo, en JavaScript puede decir:
this_php_line_number = <?= __LINE__ ?>;
Sin embargo, si no tiene cuidado, el número de línea de PHP puede ser diferente del número de línea de JavaScript, porque PHP "come" las líneas de origen antes de que el navegador las vea. Entonces, el problema es asegurarse de que los números de línea de PHP y JavaScript sean los mismos. Si son diferentes, el uso del depurador de JavaScript del navegador es mucho menos agradable.
Puede asegurarse de que los números de línea sean los mismos al incluir una declaración PHP que escriba el número correcto de líneas nuevas necesarias para sincronizar los números de línea del lado del servidor (PHP) y del lado del navegador (JavaScript).
Así es como se ve mi 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__); ?> *** -->
La clave es esta declaración de PHP:
echo str_repeat("\n",__LINE__-6);
Eso arroja suficientes líneas nuevas para que el número de línea visto por JavaScript sea el mismo que el número de línea de PHP. Todas las definiciones de funciones de PHP, etc. están en la parte superior, delante de esa línea.
Después de esa línea, restrinjo mi uso de PHP al código que no cambia los números de línea.
El "-6" explica el hecho de que mi código PHP comienza en la línea 8. Si inicia su código PHP antes, reducirá ese número. Algunas personas ponen su PHP en la parte superior, incluso antes que DOCTYPE.
(La línea de meta viewport deshabilita el "aumento de fuente" de Android Chrome según estas preguntas y respuestas de Stack Overflow: Chrome en Android cambia el tamaño de la fuente . Considérelo un modelo estándar, que toda página web necesita).
La siguiente línea es solo para verificar que no me he equivocado. Visto en el depurador del navegador, o haciendo clic derecho / save-web-page, se convierte en un comentario HTML que muestra el nombre correcto del archivo fuente y el número de línea:
<!-- *** this is line <?php echo __LINE__ . ' of ' . basename(__FILE__); ?> *** -->
se convierte en:
<!-- *** this is line 1234 of my_file.php *** -->
Ahora, siempre que vea un número de línea, ya sea en un mensaje de error o en el depurador de JavaScript, es correcto. Los números de línea de PHP y los números de línea de JavaScript son siempre consistentes e idénticos.