¿Cómo puedo determinar el número de línea actual en JavaScript?

Respuestas:

69

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.

z5h
fuente
3
No funcionará en IE, la lineNumberpropiedad no existe en los objetos de error. Tampoco stack:-)
Andy E
1
hay un número de línea en algún lugar de IE. Lo sé porque cuando mi javascript arroja un error dice que está en una línea con un número superior a 100 millones.
Malfist
No obtengo el número correcto, es 1350 cuando debería ser 1250.
Fzs2
1
Problema: si está utilizando PHP, el "código fuente" visto por JavaScript no es el código fuente original, por lo que tiene los números de línea incorrectos. (Eso es probablemente lo que le está sucediendo a Hermann). ¿Alguien sabe cómo hacer que JavaScript vea los números de línea del código fuente PHP original? La solución probablemente implica algún tipo de generación de "mapa de origen", pero no puedo encontrar cómo hacerlo. Seguramente este es un problema resuelto, ¿verdad?
Dave Burton
Nota: a veces, el número de pila / línea no está disponible cuando se construye el objeto Error, solo cuando se lanza, por ejemplo, en Google Apps Script; en ese caso, consulte esta respuesta para la solución.
user202729
38

Puedes usar:

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

test();
baligena
fuente
1
De lejos, la solución más simple e incluso funciona en MS Edge.
Danger
27

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];
}
jwatt
fuente
Gracias. Adapté tu sugerencia a esto: stackoverflow.com/a/37081135/470749
Ryan
1
Si ajusta la expresión regular, puede devolver tanto números de línea como de columna: lo var frameRE = /:(\d+:\d+)[^\d]*$/;cual es mucho más útil, especialmente cuando el JS se reduce a una línea larga.
Quinn Demandado
Advertencia, no funciona en los scripts de ViolentMonkey para Chrome; obtendrá un número falso, no sé por qué.
hanshenrik
5

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

Inyecta el siguiente fragmento de código a tu código:

console.debug("line:", /\(file:[\w\d/.-]+:([\d]+)/.exec(new Error().stack)[1]);
crishushu
fuente
sustituir el nombre de protocolo, según sea necesario (por ejemplo, "http:")
crishushu
1
No pude hacer que esto funcionara. Yo entiendo TypeError: /\(http:[\w\d/.-]+:([\d]+)/.exec(...) is null.
Ryan
2

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.onerrorno está definido / manejado en WebKit u Opera (la última vez que verifiqué)

scunliffe
fuente
1
Tenga en cuenta que window.onerror no funciona en webkit: bugs.webkit.org/show_bug.cgi?id=8519
Annie
1
Interesante. Incluso puede crear una función especial 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.
z5h
0

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

Viree
fuente
-2

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.

Dave Burton
fuente