function main()
{
Hello();
}
function Hello()
{
// How do you find out the caller function is 'main'?
}
¿Hay alguna manera de averiguar la pila de llamadas?
javascript
callstack
Ray Lu
fuente
fuente
Respuestas:
Tenga en cuenta que esta característica no es estándar , de
Function.caller
:La siguiente es la respuesta anterior de 2008, que ya no es compatible con Javascript moderno:
fuente
arguments.callee.caller.name
obtendrá el nombre de la función.'use strict';
podría ayudar.arguments
Se puede acceder desde una función en modo estricto, sería estúpido desaprobar eso. simplemente no de la función. argumentos del exterior. Además, si tiene un argumento con nombre, la forma de los argumentos [i] no rastreará los cambios que realice en la versión con nombre dentro de la función.StackTrace
Puede encontrar todo el seguimiento de la pila utilizando el código específico del navegador. Lo bueno es que alguien ya lo hizo ; Aquí está el código del proyecto en GitHub .
Pero no todas las noticias son buenas:
Es muy lento obtener el seguimiento de la pila, así que tenga cuidado (lea esto para obtener más información).
Deberá definir nombres de funciones para que el seguimiento de la pila sea legible. Porque si tienes un código como este:
Google Chrome alertará
... kls.Hello ( ...
pero la mayoría de los navegadores esperarán un nombre de función justo después de la palabra clavefunction
y lo tratarán como una función anónima. Ni siquiera Chrome podrá usar elKlass
nombre si no le das el nombrekls
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 hacerlo.No todos los navegadores le brindan la misma información. Es decir, parámetros, columna de código, etc.
Nombre de la función del llamante
Por cierto, si solo desea el nombre de la función de llamada (en la mayoría de los navegadores, pero no IE) puede usar:
Pero tenga en cuenta que este nombre será el que aparece después de la
function
palabra clave. No encontré ninguna manera (incluso en Google Chrome) para obtener más que eso sin obtener el código de toda la función.Código de función del llamante
Y resumiendo el resto de las mejores respuestas (por Pablo Cabrera, Nourdine y Greg Hewgill). Lo único que puede usar entre navegadores y realmente seguro es:
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 llamada (aunque no son de navegador cruzado).
fuente
Function.caller
según la respuesta de @ GregFunction.caller
No funcionará en modo estricto, sin embargo.Sé que mencionó "en Javascript", pero si el propósito es la depuración, creo que es más fácil usar las herramientas de desarrollador de su navegador. Así es como se ve en Chrome: simplemente suelte el depurador donde desee investigar la pila.
fuente
Para recapitular (y hacerlo más claro) ...
este codigo:
es equivalente a esto:
Claramente, el primer bit es más portátil, ya que puede cambiar el nombre de la función, decir "Hola" a "Ciao", y aún así hacer que todo funcione.
En este último caso, en caso de que decida refactorizar el nombre de la función invocada (Hola), deberá cambiar todas sus apariciones :(
fuente
Puede obtener el seguimiento completo de la pila:
Hasta que llama es
null
.Nota: causa un bucle infinito en las funciones recursivas.
fuente
Yo suelo usar
(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 eso llegué a esta página en primer lugar.(Estoy usando esto para recopilar pilas de llamadas en un constructor de bajo nivel durante la ejecución, para verlas y depurarlas más tarde, por lo que establecer un punto de interrupción no es útil, ya que será golpeado miles de veces)
fuente
'use strict';
esté en su lugar. Me dio la información que necesitaba, ¡gracias!Si no va a ejecutarlo en IE <11, entonces console.trace () sería adecuado.
fuente
Puede usar Function.Caller para obtener la función de llamada. El antiguo método que usa argumento.caller se considera obsoleto.
El siguiente código ilustra su uso:
Notas sobre argumentos obsoletos.caller: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller
Tenga en cuenta que Function.caller no es estándar: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller
fuente
Cannot access caller property of a strict mode function
Yo haría esto:
fuente
fuente
arguments.callee.caller.toString()
Es más seguro de usar
*arguments.callee.caller
ya quearguments.caller
está en desuso ...fuente
arguments.callee
también está en desuso en ES5 y se elimina en modo estricto.arguments.callee
fue una mala solución a un problema que ahora se ha resuelto mejor developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Parece que esta es una pregunta bastante resuelta, pero recientemente descubrí que la persona que llama no está permitida en 'modo estricto', así que para mi propio uso escribí una clase que obtendrá la ruta desde donde se llama. Es parte de una pequeña biblioteca auxiliar y, si desea utilizar el código de forma independiente, cambie el desplazamiento utilizado para devolver el seguimiento de la pila de la persona que llama (use 1 en lugar de 2)
fuente
function a(){ function b(){ function c(){ return ScriptPath(); } return c(); } return b(); } a()
en la consola (no lo he probado en un archivo), pero parece tener una idea razonable. Debería ser votado de todos modos para mayor visibilidad.Intenta acceder a esto:
fuente
Solo consola registre su pila de errores. Entonces puedes saber cómo te llaman
fuente
Tanto en ES6 como en modo estricto, use lo siguiente para obtener la función de llamada
Tenga en cuenta que, la línea anterior arrojará una excepción, si no hay llamador o no hay una pila anterior. Usar en consecuencia.
fuente
console.log((new Error()).stack.split("\n")[1].trim().split(" ")[1])
Actualización 2018
caller
está prohibido en modo estricto . Aquí hay una alternativa usando laError
pila (no estándar) .La siguiente función parece hacer el trabajo en Firefox 52 y Chrome 61-71, aunque su implementación hace muchas suposiciones sobre el formato de registro de los dos navegadores y debe usarse con precaución, dado que arroja una excepción y posiblemente ejecuta dos expresiones regulares. coincidencias antes de hacerse.
fuente
Quería agregar mi violín aquí para esto:
http://jsfiddle.net/bladnman/EhUm3/
Probé esto es Chrome, Safari e IE (10 y 8). Funciona bien. Solo hay 1 función que importa, así que si te asusta el gran violín, lee a continuación.
Nota: Hay una buena cantidad de mi propio "repetitivo" en este violín. Puede eliminar todo eso y usar divisiones si lo desea. Es solo un "conjunto de funciones ultra seguro" en el que he llegado a confiar.
También hay una plantilla "JSFiddle" que utilizo para muchos violines para simplemente tocar el violín rápidamente.
fuente
String.prototype.trim = trim;
Si solo desea el nombre de la función y no el código, y desea una solución independiente del navegador, use lo siguiente:
Tenga en cuenta que lo anterior devolverá un error si no hay una función de llamada ya que no hay ningún elemento [1] en la matriz. Para evitarlo, use lo siguiente:
fuente
Sólo quiero hacerle saber que en PhoneGap / androide del
name
no se parece estar funcionando. Peroarguments.callee.caller.toString()
hará el truco.fuente
Aquí, todo menos el
functionname
es eliminadocaller.toString()
, con RegExp.fuente
Aquí hay una función para obtener el stacktrace completo :
fuente
La respuesta de heystewart y la respuesta de JiarongWu mencionaron que el
Error
objeto tiene acceso astack
.Aquí hay un ejemplo:
Los diferentes navegadores muestran la pila en diferentes formatos de cadena:
Safari : Caller is: main@https://stacksnippets.net/js:14:8 Firefox : Caller is: main@https://stacksnippets.net/js:14:3 Chrome : Caller is: at main (https://stacksnippets.net/js:14:3) IE Edge : Caller is: at main (https://stacksnippets.net/js:14:3) IE : Caller is: at main (https://stacksnippets.net/js:14:3)
La mayoría de los navegadores configurarán la pila con
var stack = (new Error()).stack
. En Internet Explorer, la pila estará indefinida: debe lanzar una excepción real para recuperar la pila.Conclusión: Es posible determinar que "main" es la persona que llama a "Hello" usando el
stack
en elError
objeto. De hecho, funcionará en los casos en que el enfoquecallee
/caller
no funcione. También le mostrará el contexto, es decir, el archivo fuente y el número de línea. Sin embargo, se requiere un esfuerzo para hacer que la solución sea multiplataforma.fuente
Tenga en cuenta que no puede usar Function.caller en Node.js, use el paquete caller-id en su lugar. Por ejemplo:
fuente
Prueba el siguiente código:
Trabajó para mí en Firefox-21 y Chromium-25.
fuente
arguments.callee
ha quedado en desuso por muchos años .Otra forma de evitar este problema es simplemente pasar el nombre de la función de llamada como parámetro.
Por ejemplo:
Ahora, podría llamar a la función de esta manera:
Mi ejemplo utiliza una verificación codificada del nombre de la función, pero podría usar fácilmente una instrucción de cambio o alguna otra lógica para hacer lo que quiera allí.
fuente
Hasta donde yo sé, tenemos dos formas para esto de fuentes dadas como esta:
argumentos.caller
Function.caller
Creo que tienes tu respuesta :).
fuente
Por qué todas las soluciones anteriores parecen una ciencia espacial. Mientras tanto, no debería ser más complicado que este fragmento. Todos los créditos a este chico
¿Cómo se encuentra la función de llamada en JavaScript?
fuente
Estoy tratando de abordar la pregunta y la recompensa actual con esta pregunta.
La recompensa requiere que la persona que llama se obtenga en modo estricto , y la única forma en que puedo ver esto es refiriéndose a una función declarada fuera del modo estricto.
Por ejemplo, lo siguiente no es estándar, pero se ha probado con versiones anteriores (29/03/2016) y actuales (1 de agosto de 2018) de Chrome, Edge y Firefox.
fuente
Si realmente necesita la funcionalidad por alguna razón y desea que sea compatible con todos los navegadores y no se preocupe por cosas estrictas y sea compatible con versiones posteriores, pase esta referencia:
fuente
Creo que el siguiente código puede ser útil:
Ejecute el código:
El registro se ve así:
fuente