Ответ 1
Быстрая и грязная в браузерах на базе Gecko:
new Error().stack
Вы также можете вручную тралить часть стека, используя Function.prototype.caller:
var thisFunction = arguments.callee;
var caller = thisFunction.caller;
var callerCaller = caller.caller;
// ...and eventually, assuming no recursion:
var bottomCaller = ...;
assert(bottomCaller.caller === null);
Одно (возможно, большое) оговорка трюка .caller заключается в том, что он не обрабатывает рекурсию - .caller
смотрит сверху стека вниз, чтобы найти первый экземпляр функции в стеке, а затем возвращает непосредственный вызывающий, поэтому, не будучи осторожным, вы можете бесконечно искать вызывающих абонентов.
Еще одна оговорка к caller
заключается в следующем: если в любом из ваших кодов используется строгий режим ECMAScript 5, свойство caller
функций строгого режима (или функций, которые сами вызывались из строгих функций режима) так называемая "ядовитая таблетка", которая бросает TypeError
при доступе. Свойство caller
"связанных" функций (созданных методом ES5 Function.prototype.bind
) также является ядовитой таблеткой. Эти ограничения нарушают общий алгоритм стековой ходьбы, хотя можно представить, как использовать его для использования (это могут быть функции входа и выхода для аннотирования).
Заметьте, что стековая ходьба, как это, не является отличной идеей в производственном коде (в качестве быстрого взлома для отладки, отлично, tho); в тот момент, когда вы поднимаете стек, поскольку в последнем примере несколько дороже в Mozilla JS engine, и он, вероятно, выкинет вас из машинного кода и вернется в интерпретируемый код. Кроме того, стековая прогулка - это O (n 2), что может иметь значение, если у вас есть сложные, глубокие стеки.