Pregunta ¿Cómo se entera de la función de llamada en JavaScript?


function main()
{
   Hello();
}

function Hello()
{
  // How do you find out the caller function is 'main'?
}

¿Hay alguna forma de averiguar la pila de llamadas?


716
2017-11-11 09:04


origen


Respuestas:


function Hello()
{
    alert("caller is " + Hello.caller);
}

Tenga en cuenta que esta característica es no estándar, de Function.caller:

No estándar
  Esta función no es estándar y no está en una pista de estándares. No lo use en sitios de producción frente a la Web: no funcionará para todos los usuarios. También puede haber grandes incompatibilidades entre implementaciones y el comportamiento puede cambiar en el futuro.


La siguiente es la respuesta anterior de 2008, que ya no es compatible con el Javascript moderno:

function Hello()
{
    alert("caller is " + arguments.callee.caller.toString());
}

902
2017-11-11 09:07



StackTrace

Puede encontrar la traza completa de la pila usando el código específico del navegador. Lo bueno es alguien ya lo hizo; aquí está el código de proyecto en GitHub.

Pero no todas las noticias son buenas:

  1. Es realmente lento obtener el seguimiento de la pila, así que ten cuidado (lee esta para más).

  2. Tendrá que definir los nombres de las funciones para que el trazo de la pila sea legible. Porque si tienes un código como este:

    var Klass = function kls() {
       this.Hello = function() { alert(printStackTrace().join('\n\n')); };
    }
    new Klass().Hello();
    

    Google Chrome alertará ... kls.Hello ( ... pero la mayoría de los navegadores esperan un nombre de función justo después de la palabra clave function y lo tratará como una función anónima. Ni siquiera Chrome podrá usar el Klass nombre si no le das el nombre kls a la función.

    Y por cierto, puede pasar a la función printStackTrace la opción {guess: true} pero no encontré ninguna mejora real al hacer eso.

  3. No todos los navegadores le dan la misma información. Es decir, parámetros, columna de código, etc.


Nombre de la función del llamante

Por cierto, si solo quieres el nombre de la función de llamada (en la mayoría de los navegadores, pero no en IE) puedes usar:

arguments.callee.caller.name

Pero tenga en cuenta que este nombre será el que está después del function palabra clave. No encontré manera (ni siquiera en Google Chrome) de obtener más que eso sin obtener el código de toda la función.


Código de función de llamada

Y resumiendo el resto de las mejores respuestas (por Pablo Cabrera, nourdine y Greg Hewgill). El único navegador cruzado y algo realmente seguro que puedes usar es:

arguments.callee.caller.toString();

Que mostrará el código de la función de llamada. Lamentablemente, eso no es suficiente para mí, y es por eso que le doy consejos para StackTrace y el nombre de la función de la persona que llama (aunque no son un navegador cruzado).


139
2017-09-24 16:38



Para recapitular (y hacerlo más claro) ...

este código:

function Hello() {
    alert("caller is " + arguments.callee.caller.toString());
}

es equivalente a esto:

function Hello() {
    alert("caller is " + Hello.caller.toString());
}

Claramente, el primer bit es más portátil, ya que puede cambiar el nombre de la función, digamos de "Hola" a "Ciao", y aún así hacer que todo funcione.

En este último, en caso de que decida refactorizar el nombre de la función invocada (Hola), debería cambiar todas sus ocurrencias :(


48
2018-04-06 13:47



Puedes obtener la stacktrace completa:

arguments.callee.caller
arguments.callee.caller.caller
arguments.callee.caller.caller.caller

Hasta que llama es null.

Nota: causa un bucle infinito en las funciones recursivas.


46
2017-10-28 22:33



Sé que mencionó "en Javascript", pero si el propósito es la depuración, creo que es más fácil simplemente usar las herramientas de desarrollo de su navegador. Así es como se ve en Chrome: enter image description hereSimplemente suelte el depurador donde desea investigar la pila.


30
2018-02-03 00:28



Usualmente uso (new Error()).stack en Chrome. Lo bueno es que esto también le da los números de línea donde la persona que llama llamó a la función. La desventaja es que limita la longitud de la pila a 10, por lo que llegué a esta página en primer lugar.

(Estoy usando esto para recolectar callstacks en un constructor de bajo nivel durante la ejecución, para ver y depurar más tarde, por lo que establecer un punto de interrupción no es útil ya que se golpeará miles de veces)


25
2018-05-07 14:15



Puede usar Function.Caller para obtener la función de llamada. El método anterior que usa argument.caller se considera obsoleto.

El siguiente código ilustra su uso:

function Hello() { return Hello.caller;}

Hello2 = function NamedFunc() { return NamedFunc.caller; };

function main()
{
   Hello();  //both return main()
   Hello2();
}

Notas sobre argument.caller obsoleto: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller

Tenga en cuenta Function.caller no es estándar: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller


19
2018-06-06 21:01



function Hello() {
    alert(Hello.caller);
}

17
2017-11-11 10:56