2011-12-05 8 views
7

¿Existe alguna manera de determinar la profundidad de la pila de todas las funciones que se ejecutan en javascript mediante el uso de javascript?determinar la profundidad de la pila en javascript mediante javascript

Estoy pensando que podría implicar la modificación del prototipo Function, pero realmente no tengo ni idea.

Además, sería bueno poder romper en cualquier momento que la profundidad de la pila fuera lo suficientemente alta.

La razón para esto es que tengo un stack overflow error in IE which is apparently not debuggable. Soy flojo y prefiero no tener que buscar el código que estoy buscando para encontrar la causa.

Gracias por ayudar a mi pereza.

+0

Puede indicar una función a otra e incrementar una variable global hasta que el navegador arroje un error de desbordamiento de pila. Luego imprime su variable de contador y tiene un valor bruto para la profundidad de la pila. – Bojangles

Respuesta

5

ECMAscript admitió durante bastante tiempo la propiedad Function.prototype.caller. Incluso si es obsoleto en ES5 estricto, IE aún debería soportarlo. Entonces, básicamente, podrías recorrer las funciones involucradas.

function one() { 
    two(); 
} 

function two() { 
    three(); 
} 

function three() { 
    var caller = three.caller; 

    console.log('caller was: ', caller.name); 

    while(caller = caller.caller) { 
      console.log('caller was: ', caller.name); 
    } 
} 

(function outer() { 
    one(); 
}()); 

Eso sería:

caller was: two 
caller was: one 
caller was: _outer 

Por lo tanto, si usted sabe en qué función ocurre un error, de esa manera se obtiene la respuesta todo el camino hasta la forma en que este método se llamó originalmente. Si está justo después de la profundidad, puede contar cuántas interacciones se realizaron sobre la propiedad caller.caller. Al menos IE8 debería ser compatible con la declaración "depurador", que solo podría invocar en esa secuencia de comandos para llevar el depurador al escenario.

+0

Esto se parece mucho a lo que estoy buscando ... pero la cuestión es que tendría que aplicar esto de alguna manera a todas las funciones sin tener que agregarlo a su código. ¿Sabes lo que quiero decir? Gracias. – user420667

+1

@ user420667: No creo que exista una forma "fácil" de hacerlo sobre el Function.prototype. Básicamente, necesitarías hacer un ciclo recursivo sobre todos los objetos (comenzando con 'ventana') y verificar las funciones. Si encontró uno, necesita enganchar/parchar el método y llamar al código provisto arriba. Podría funcionar. – jAndy

+0

oh, vale ... algo así para cada función ... newFunction = function() {oldFunction (args); if (CallerDepth()> MaxAllowedDepth) {depurador;}}; oldFunction = newFunction; ??? No creo que sea correcto. Además, como dijiste, asegúrate de que de alguna manera se llame antes que cualquier otra función, y asegúrate de que la lista de funciones para iterar se crea antes de modificar cualquier función. – user420667

4
function stackDepth() { 
    var c=stackDepth.caller, depth=0; 
    while (c) { c = c.caller; depth++; } 
    return depth; 
} 

Chrome parece pensar que la profundidad de la pila de la consola ya es 3, así que tal vez para cada entorno JavaScript que había necesidad de determinar una profundidad inicial de referencia y restar de eso.

stackDepth(); // => 3 
(function(){return stackDepth();})(); // => 4 
+0

interesante. Me pregunto cuáles son los 3 objetos de nivel superior. ¿ventana? ¿documento? – user420667

Cuestiones relacionadas