Question Comment trouvez-vous la fonction d'appelant en JavaScript?


function main()
{
   Hello();
}

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

Y at-il un moyen de trouver la pile d'appel du tout?


716
2017-11-11 09:04


origine


Réponses:


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

Notez que cette fonctionnalité est non standard, de Function.caller:

Non standard
  Cette fonctionnalité est non standard et n'est pas sur une piste de normalisation. Ne l'utilisez pas sur des sites de production tournés vers le Web: cela ne fonctionnera pas pour tous les utilisateurs. Il peut également y avoir de grandes incompatibilités entre les implémentations et le comportement peut changer dans le futur.


Ce qui suit est la vieille réponse de 2008, qui n'est plus supportée en Javascript moderne:

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

902
2017-11-11 09:07



Trace de la pile

Vous pouvez trouver la totalité de la trace de la pile en utilisant le code spécifique au navigateur. Ce qui est bien quelqu'un l'a déjà fait; Voici la code du projet sur GitHub.

Mais toutes les nouvelles ne sont pas bonnes:

  1. Il est vraiment lent d'obtenir la trace de la pile alors soyez prudent (lisez ce pour plus).

  2. Vous devrez définir des noms de fonction pour que la trace de la pile soit lisible. Parce que si vous avez du code comme ceci:

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

    Google Chrome alertera ... kls.Hello ( ... mais la plupart des navigateurs s'attendent à un nom de fonction juste après le mot-clé function et le traiter comme une fonction anonyme. Un même pas Chrome sera en mesure d'utiliser le Klass nom si vous ne donnez pas le nom kls à la fonction.

    Et en passant, vous pouvez passer à la fonction printStackTrace l'option {guess: true} mais je n'ai trouvé aucune amélioration réelle en faisant cela.

  3. Tous les navigateurs ne vous donnent pas la même information. C'est-à-dire, paramètres, colonne de code, etc.


Nom de la fonction de l'appelant

En passant, si vous voulez seulement le nom de la fonction de l'appelant (dans la plupart des navigateurs, mais pas IE), vous pouvez utiliser:

arguments.callee.caller.name

Mais notez que ce nom sera celui après le function mot-clé. Je n'ai trouvé aucun moyen (même sur Google Chrome) d'obtenir plus que cela sans obtenir le code de l'ensemble de la fonction.


Code de fonction de l'appelant

Et résumant le reste des meilleures réponses (par Pablo Cabrera, nourdine, et Greg Hewgill). La seule chose que vous pouvez utiliser est:

arguments.callee.caller.toString();

Ce qui montrera le code de la fonction de l'appelant. Malheureusement, cela ne me suffit pas, et c'est pourquoi je vous donne des conseils pour le StackTrace et la fonction de l'appelant Name (bien qu'ils ne soient pas cross-browser).


139
2017-09-24 16:38



Pour récapituler (et le rendre plus clair) ...

ce code:

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

est équivalent à ceci:

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

Clairement, le premier bit est plus portable, puisque vous pouvez changer le nom de la fonction, par exemple de "Bonjour" à "Ciao", et continuer à faire fonctionner le tout.

Dans ce dernier, si vous décidez de refactoriser le nom de la fonction invoquée (Hello), vous devrez changer toutes ses occurrences :(


48
2018-04-06 13:47



Vous pouvez obtenir la pile complète:

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

Jusqu'à ce que l'appelant soit null.

Note: cela provoque une boucle infinie sur les fonctions récursives.


46
2017-10-28 22:33



Je sais que vous avez mentionné "en Javascript", mais si le but est le débogage, je pense qu'il est plus facile d'utiliser simplement les outils de développement de votre navigateur. Voici à quoi cela ressemble dans Chrome: enter image description hereDéposez simplement le débogueur où vous voulez étudier la pile.


30
2018-02-03 00:28



J'utilise habituellement (new Error()).stack dans Chrome. La bonne chose est que cela vous donne également les numéros de ligne où l'appelant a appelé la fonction. L'inconvénient est qu'il limite la longueur de la pile à 10, c'est pourquoi je suis venu à cette page en premier lieu.

(J'utilise ceci pour collecter des callstacks dans un constructeur de bas niveau pendant l'exécution, pour les visualiser et les déboguer plus tard, donc mettre un breakpoint n'est pas utile car il sera touché des milliers de fois)


25
2018-05-07 14:15



Vous pouvez utiliser Function.Caller pour obtenir la fonction d'appel. L'ancienne méthode utilisant argument.caller est considérée comme obsolète.

Le code suivant illustre son utilisation:

function Hello() { return Hello.caller;}

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

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

Remarques à propos de argument.caller obsolète: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller

Soyez conscient que Function.caller est non-standard: 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



Si vous ne l'exécutez pas dans IE <11 alors console.trace () conviendrait.

function main() {
    Hello();
}

function Hello() {
    console.trace()
}

main()
// Hello @ VM261:9
// main @ VM261:4

17
2018-01-18 10:58



Il est plus sûr d'utiliser *arguments.callee.caller depuis arguments.caller est déconseillé...


16
2017-11-11 09:50