Voici une fonction qui fonctionne dans tous les principaux navigateurs, bien que cela ne fonctionnera pas dans ECMAScript 5 en mode strict, car arguments.callee
et caller
ont été supprimés en mode strict.
function getCallStackSize() {
var count = 0, fn = arguments.callee;
while ( (fn = fn.caller) ) {
count++;
}
return count;
}
Exemple:
function f() { g(); }
function g() { h(); }
function h() { alert(getCallStackSize()); }
f(); // Alerts 3
Mise à JOUR le 1er novembre 2011
Dans l'ES5 mode strict, il n'y a tout simplement pas de moyen de parcourir la pile d'appel. La seule option qui reste est d'analyser la chaîne de caractères retournée par new Error().stack
, ce qui est non-standard, pas de prise en charge universelle et évidemment problématique, et même cela peut ne pas être possible pour toujours.
Mise à JOUR le 13 août 2013
Cette méthode est également limitée par le fait qu'une fonction qui est appelée plus d'une fois dans une seule pile d'appel (par exemple, via la récursivité) va jeter getCallStackSize()
dans une boucle infinie (comme l'a fait remarquer @Randomblue dans les commentaires). Une version améliorée de l' getCallStackSize()
ci-dessous: il conserve une trace de fonctions qu'il a vu avant pour éviter de rentrer dans une boucle infinie. Toutefois, la valeur retournée est le nombre de différents objets de fonction dans la pile des appels avant de rencontrer une répétition plutôt que la vraie taille de la pile d'appel complète. C'est le meilleur que vous pouvez faire, malheureusement.
var arrayContains = Array.prototype.indexOf ?
function(arr, val) {
return arr.indexOf(val) > -1;
} :
function(arr, val) {
for (var i = 0, len = arr.length; i < len; ++i) {
if (arr[i] === val) {
return true;
}
}
return false;
};
function getCallStackSize() {
var count = 0, fn = arguments.callee, functionsSeen = [fn];
while ( (fn = fn.caller) && !arrayContains(functionsSeen, fn) ) {
functionsSeen.push(fn);
count++;
}
return count;
}