function main()
{
Hello();
}
function Hello()
{
// How do you find out the caller function is 'main'?
}
Есть ли способ узнать стек вызовов?
Когда это будет полезно для отладки?
@AndersonGreen, когда у вас есть, например, метод рендеринга шаблона по умолчанию и вы видите, что он вызывается дважды. Вместо того, чтобы копаться в тысячах LoC или усердно работать с отладчиком, вы можете просто увидеть, какой был стек в то время.
чтобы увидеть трассировку стека, используйте console.trace () для chrome. хотя не знаю о других
Это не должно использоваться для «изменения» поведения (1-й комментарий). Подумайте о концепции промежуточного программного обеспечения, где вы можете просто проверить, вызывает ли вызывающий другой именованное промежуточное программное обеспечение ...
@ lukas.pukenis Использование stacktracejs.com также может быть вариантом, кроссбраузерность, конечно, потому что это чистый Javascript, поэтому нет JQuery или другого зависимого.
Для отладки это также может быть полезно при работе с событиями. При остановке для трассировки вы фактически нарушаете цепочку событий, которые хотите проверить. Этот console.trace () спас мне день. Он работает в IE11, Firefox и Chrome.
Это также может быть полезно, если вам нужна полная трассировка стека: stackoverflow.com/questions/6715571/…
console.info((new Error()).stack.split("\n")[2].trim().split(" ")[1]) для ES6 или «строгий режим». Этот оператор вызывает исключение, если вызывающего абонента нет.
Почему это плохая идея?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


function Hello()
{
alert("caller is " + Hello.caller);
}
Обратите внимание, что эта функция - нестандартный, от Function.caller:
Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
Ниже приводится старый ответ 2008 года, который больше не поддерживается в современном Javascript:
function Hello()
{
alert("caller is " + arguments.callee.caller.toString());
}
arguments.callee.caller.name получит имя функции.
он бросает arguments.callee.caller is null в приложение Mozilla (xulrunner 1.9.2)
@Incognito, как вы, несомненно, уже догадались, любую функцию можно преобразовать в строку. Я вообще не могу придумать никаких трюков ... Источник.
«Свойства 'вызывающий', 'вызываемый' и 'аргументы' не могут быть доступны для функций строгого режима или объектов аргументов для их вызовов» - они устарели в ES5 и удалены в строгом режиме.
arguments.callee.caller.name не работал у меня, поэтому, чтобы просто получить возвращаемое имя функции вызывающего абонента, я использовал это: 'arguments.callee.caller.toString (). split (' (') [0]'
Это будет работать, только если вы не используете строгий режим. Так что удаление 'use strict'; может помочь.
Хм, аргументы нельзя использовать в строгом режиме? Тогда как я могу использовать список переменных аргументов без него?
Доступ к arguments МОЖЕТ быть доступен из функции в строгом режиме, было бы глупо отказываться от этого. просто не из функции. аргументов извне. Кроме того, если у вас есть именованный аргумент, его форма arguments [i] не будет отслеживать изменения, которые вы вносите в именованную версию внутри функции.
Этот метод устарел с тех пор, как этот пост был внесен в список в 2011 году. Теперь предпочтительным методом является Function.caller (по состоянию на 2015 год).
@Greg У вас есть источник (например, URL-адрес) для этого?
Это нестандартно (на данный момент), но URL-адрес: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@RocketHazmat callee.name даст пустую строку, если функция анонимна.
Важно отметить, что arguments.callee устарел и недоступен в строгом режиме. посмотрим, почему здесь: stackoverflow.com/questions/103598/…
Function.caller не работает для большей части ES6: это запрещенное расширение для функций строгого режима, которые, если они определены, должны выдавать при доступе. И ES6 модули всегда в строгом режиме. Chrome V8 реализует это; caller есть только в функциях небрежного режима. Это по соображениям безопасности.
Всем, кто ищет более современное решение, которое работает в Typescript и фреймворках, таких как Angular, используйте console.info((new Error).stack);.
в моем случае он возвращает значение null
@ReinBaarsma дает одну большую строку
@RocketHazmat старый комментарий поста, но спасибо! Действительно, «arguments.callee.caller.name» получит имя, и это очень поможет при поддержке старого сайта, где много событий «onclick» или «on-something ()» прикреплены к элементам, которые вызывают тот же хендлер! Часто исходный код передает только "this", что хорошо для наследования объекта, но НЕ может предлагать тип события! В новых браузерах доступно 'event' или хотя бы 'window.event', но есть исключения! Теперь, когда ни один из них недоступен, у меня есть план Б, поскольку тип события может быть получен из имени вызывающего абонента! ПОТРЯСАЮЩЕ!
Безопаснее использовать *arguments.callee.caller, так как arguments.caller - это устарел ...
arguments.callee также устарел в ES5 и удаляется в строгом режиме.
Есть ли альтернатива? Обновлено: arguments.callee был плохим решением проблемы, которая теперь решена лучше developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Попробуйте получить доступ к этому:
arguments.callee.caller.name
Это был устарел много лет.
function Hello() {
alert(Hello.caller);
}
И просто для имени функции используйте Hello.caller.name
такой же, как arguments.callee.caller.toString()
Это должен быть правильный ответ, по крайней мере, на 2016 год.
Это не соответствует стандарту, но будет работать с ECMAScript 5.
@ Дэниел: нет, не должно. См. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Подведем итоги (и сделаем это яснее) ...
этот код:
function Hello() {
alert("caller is " + arguments.callee.caller.toString());
}
эквивалентно этому:
function Hello() {
alert("caller is " + Hello.caller.toString());
}
Очевидно, что первый бит более переносимый, поскольку вы можете изменить имя функции, скажем, с «Hello» на «Ciao», и при этом заставить все это работать.
В последнем случае, если вы решите реорганизовать имя вызываемой функции (Hello), вам придется изменить все ее вхождения :(
arguments.callee.caller всегда равен нулю в Chrome 25.0.1364.5 dev
Вы можете найти всю трассировку стека, используя код браузера. Хорошая вещь - кто-то уже сделал это; вот код проекта на GitHub.
Но не все новости хороши:
Получить трассировку стека очень медленно, поэтому будьте осторожны (подробнее см. это).
Вам нужно будет определить имена функций, чтобы трассировка стека была удобочитаемой. Потому что, если у вас есть такой код:
var Klass = function kls() {
this.Hello = function() { alert(printStackTrace().join('\n\n')); };
}
new Klass().Hello();
Google Chrome предупредит ... kls.Hello ( ..., но большинство браузеров ожидают имени функции сразу после ключевого слова function и будут рассматривать его как анонимную функцию. Даже Chrome не сможет использовать имя Klass, если вы не дадите функции имя kls.
И, кстати, вы можете передать функции printStackTrace опцию {guess: true}, но я не нашел никаких реальных улучшений, сделав это.
Не все браузеры предоставляют одинаковую информацию. То есть параметры, столбец кода и т. д.
Кстати, если вам нужно только имя вызывающей функции (в большинстве браузеров, но не в IE), вы можете использовать:
arguments.callee.caller.name
Но учтите, что это имя будет после ключевого слова function. Я не нашел способа (даже в Google Chrome) получить больше, не получив кода всей функции.
И резюмируя остальные лучшие ответы (Пабло Кабрера, Нурдин и Грег Хьюджилл). Единственная кроссбраузерная и действительно безопасная вещь, которую вы можете использовать:
arguments.callee.caller.toString();
Что покажет код вызывающей функции. К сожалению, для меня этого недостаточно, и поэтому я даю вам советы по StackTrace и имени вызывающей функции (хотя они не являются кроссбраузерными).
возможно, вам стоит добавить Function.caller на @ Ответ Грега
Однако Function.caller не работает в строгом режиме.
Вы можете получить полную трассировку стека:
arguments.callee.caller
arguments.callee.caller.caller
arguments.callee.caller.caller.caller
Пока вызывающий абонент не будет null.
Примечание: это вызывает бесконечный цикл рекурсивных функций.
Извините за поздний ответ, но я не видел вашего комментария раньше; только для случая рекурсии это не работает, в других случаях должно работать.
Если вам нужно просто имя функции, а не код, и вам нужно решение, не зависящее от браузера, используйте следующее:
var callerFunction = arguments.callee.caller.toString().match(/function ([^\(]+)/)[1];
Обратите внимание, что приведенное выше вернет ошибку, если нет вызывающей функции, поскольку в массиве нет элемента [1]. Чтобы обойти эту проблему, используйте следующее:
var callerFunction = (arguments.callee.caller.toString().match(/function ([^\(]+)/) === null) ? 'Document Object Model': arguments.callee.caller.toString().match(/function ([^\(]+)/)[1], arguments.callee.toString().match(/function ([^\(]+)/)[1]);
Это был устарел много лет.
Я хотел добавить сюда свою скрипку:
http://jsfiddle.net/bladnman/EhUm3/
Я тестировал это хром, сафари и IE (10 и 8). Работает отлично. Важна только одна функция, поэтому, если вас пугает большая рабочий пример, прочтите ниже.
Примечание: В этой скрипке есть изрядное количество моего собственного "шаблона". Вы можете удалить все это и использовать сплит, если хотите. Это просто сверхбезопасный набор функций, на которые я привык полагаться.
Там также есть шаблон "JSFiddle", который я использую для многих скрипок, чтобы просто быстро возиться.
Интересно, могли бы вы в некоторых случаях добавить «помощников» в качестве расширений для прототипа, например: String.prototype.trim = trim;
Здесь все, кроме functionname, отделено от caller.toString() с помощью RegEx.
<!DOCTYPE html>
<meta charset = "UTF-8">
<title>Show the callers name</title><!-- This validates as html5! -->
<script>
main();
function main() { Hello(); }
function Hello(){
var name = Hello.caller.toString().replace(/\s\([^#]+$|^[^\s]+\s/g,'');
name = name.replace(/\s/g,'');
if ( typeof window[name] !== 'function' )
alert ("sorry, the type of "+name+" is "+ typeof window[name]);
else
alert ("The name of the "+typeof window[name]+" that called is "+name);
}
</script>
это по-прежнему возвращает полное объявление метода
Попробуйте следующий код:
function getStackTrace(){
var f = arguments.callee;
var ret = [];
var item = {};
var iter = 0;
while ( f = f.caller ){
// Initialize
item = {
name: f.name || null,
args: [], // Empty array = no arguments passed
callback: f
};
// Function arguments
if ( f.arguments ){
for ( iter = 0; iter<f.arguments.length; iter++ ){
item.args[iter] = f.arguments[iter];
}
} else {
item.args = null; // null = argument listing not supported
}
ret.push( item );
}
return ret;
}
У меня работал в Firefox-21 и Chromium-25.
Попробуйте это для рекурсивных функций.
Похоже, что это вполне решенный вопрос, но недавно я обнаружил, что вызываемый абонент не допускается в "строгом режиме", поэтому для собственного использования я написал класс, который будет получать путь, откуда он вызывается. Это часть небольшой вспомогательной библиотеки, и если вы хотите использовать автономный код, измените смещение, используемое для возврата трассировки стека вызывающего (используйте 1 вместо 2)
function ScriptPath() {
var scriptPath = '';
try {
//Throw an error to generate a stack trace
throw new Error();
}
catch(e) {
//Split the stack trace into each line
var stackLines = e.stack.split('\n');
var callerIndex = 0;
//Now walk though each line until we find a path reference
for(var i in stackLines){
if (!stackLines[i].match(/http[s]?:///)) continue;
//We skipped all the lines with out an http so we now have a script reference
//This one is the class constructor, the next is the getScriptPath() call
//The one after that is the user code requesting the path info (so offset by 2)
callerIndex = Number(i) + 2;
break;
}
//Now parse the string for each section we want to return
pathParts = stackLines[callerIndex].match(/((http[s]?://.+/)([^/]+\.js)):/);
}
this.fullPath = function() {
return pathParts[1];
};
this.path = function() {
return pathParts[2];
};
this.file = function() {
return pathParts[3];
};
this.fileNoExt = function() {
var parts = this.file().split('.');
parts.length = parts.length != 1 ? parts.length - 1 : 1;
return parts.join('.');
};
}
У меня не работает с function a(){ function b(){ function c(){ return ScriptPath(); } return c(); } return b(); } a() в консоли (не пробовал в файле), но, похоже, у меня есть разумная идея. В любом случае должен быть одобрен для видимости.
Идея отличная. Я разбираюсь по-другому, но в приложениях nw.js это единственная идея, которая дает то, что я ищу.
Приведите пример вызова этой функции.
Просто хочу сообщить вам, что на PhoneGap / Androidname, похоже, не работает. Но arguments.callee.caller.toString() сделает свое дело.
Я знаю, что вы упомянули «в Javascript», но если целью является отладка, я думаю, что проще просто использовать инструменты разработчика вашего браузера. Вот как это выглядит в Chrome:
Просто перетащите отладчик туда, где вы хотите исследовать стек.
Это старый вопрос ... но это определенно самый современный способ сделать это на сегодняшний день.
Обычно я использую (new Error()).stack в Chrome.
Приятно то, что это также дает вам номера строк, в которых вызывающий вызывает функцию. Обратной стороной является то, что он ограничивает длину стека до 10, поэтому я и пришел на эту страницу в первую очередь.
(Я использую это для сбора стеков вызовов в низкоуровневом конструкторе во время выполнения, для просмотра и отладки позже, поэтому установка точки останова бесполезна, поскольку она будет достигнута тысячи раз)
Не могли бы вы добавить еще немного описания к предоставленному вами объяснению?
Это единственное, что я мог заставить работать, когда 'use strict'; установлен. Предоставил мне необходимую информацию - спасибо!
Что касается предела длины стека ... вы можете изменить это с помощью «Error.stackTraceLimit = Infinity».
(новая ошибка ("StackLog")). stack.split ("\ n") упрощает чтение.
Вы можете использовать Function.Caller для получения вызывающей функции. Старый метод с использованием argument.caller считается устаревшим.
Следующий код иллюстрирует его использование:
function Hello() { return Hello.caller;}
Hello2 = function NamedFunc() { return NamedFunc.caller; };
function main()
{
Hello(); //both return main()
Hello2();
}
Примечания об устаревшем аргументе. Вызывающий: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller
Имейте в виду, что Function.caller нестандартен: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller
Это правильный ответ в наши дни. Вы больше не можете использовать arguments.caller.callee. Хотелось бы, чтобы это переместили в начало, так как все остальное уже устарело.
Кажется, это невозможно в строгом режиме? Cannot access caller property of a strict mode function
Function.caller у меня тоже не работал в строгом режиме. Кроме того, по данным MDN, function.caller нестандартен и не должен использоваться в продакшене. Однако это может сработать для отладки.
У меня не было проблем с нестандартным, если он работал в Node, но это просто недопустимо в строгом режиме (я тестировал на узле 6.10). То же самое и с аргументами. Я получаю сообщение об ошибке: '' 'вызывающий' и 'аргументы' являются ограниченными свойствами функции и не могут быть доступны в этом контексте. "
Если вам действительно нужна функциональность по какой-то причине и вы хотите, чтобы она была кросс-браузерной, не беспокоилась о строгих правилах и была совместима с пересылкой, то передайте эту ссылку:
function main()
{
Hello(this);
}
function Hello(caller)
{
// caller will be the object that called Hello. boom like that...
// you can add an undefined check code if the function Hello
// will be called without parameters from somewhere else
}
Если вы не собираетесь запускать его в IE <11, то console.trace () подойдет.
function main() {
Hello();
}
function Hello() {
console.trace()
}
main()
// Hello @ VM261:9
// main @ VM261:4
Другой способ решить эту проблему - просто передать имя вызывающей функции в качестве параметра.
Например:
function reformatString(string, callerName) {
if (callerName === "uid") {
string = string.toUpperCase();
}
return string;
}
Теперь вы можете вызвать функцию следующим образом:
function uid(){
var myString = "apples";
reformatString(myString, function.name);
}
В моем примере используется жестко закодированная проверка имени функции, но вы можете легко использовать оператор switch или другую логику, чтобы делать там то, что вы хотите.
Я считаю, что это также решает проблемы кроссбраузерной совместимости по большей части. Но, пожалуйста, проверьте это, прежде чем предполагать, что это правда! (начинает потеть)
Насколько я знаю, у нас есть 2 способа сделать это из таких источников, как этот:
function whoCalled()
{
if (arguments.caller == null)
console.info('I was called from the global scope.');
else
console.info(arguments.caller + ' called me!');
}
function myFunc()
{
if (myFunc.caller == null) {
return 'The function was called from the top!';
}
else
{
return 'This function\'s caller was ' + myFunc.caller;
}
}
Думаю, у тебя есть ответ :).
Это был устарел много лет, и Function.caller не работает в строгом режиме.
Я пытаюсь ответить как на вопрос, так и на текущую награду с помощью этого вопроса.
Награда требует, чтобы вызывающий абонент был получен в режиме строгий, и единственный способ, которым я могу это сделать, - это обратиться к функции, объявленной вне строгого режима.
Например, следующее нестандартно, но было протестировано с предыдущими (29.03.2016) и текущей (1 августа 2018) версиями Chrome, Edge и Firefox.
function caller()
{
return caller.caller.caller;
}
'use strict';
function main()
{
// Original question:
Hello();
// Bounty question:
(function() { console.info('Anonymous function called by ' + caller().name); })();
}
function Hello()
{
// How do you find out the caller function is 'main'?
console.info('Hello called by ' + caller().name);
}
main();Хороший хак, но не работает для Модули ES5, которые полностью находятся в строгом режиме.
вот функция для получить полную трассировку стека:
function stacktrace() {
var f = stacktrace;
var stack = 'Stack trace:';
while (f) {
stack += '\n' + f.name;
f = f.caller;
}
return stack;
}
Почему все вышеперечисленные решения выглядят как ракетостроение. Между тем, это не должно быть сложнее этого фрагмента. Все кредиты этому парню
Как узнать функцию вызывающего абонента в JavaScript?
var stackTrace = function() {
var calls = [];
var caller = arguments.callee.caller;
for (var k = 0; k < 10; k++) {
if (caller) {
calls.push(caller);
caller = caller.caller;
}
}
return calls;
};
// when I call this inside specific method I see list of references to source method, obviously, I can add toString() to each call to see only function's content
// [function(), function(data), function(res), function(l), function(a, c), x(a, b, c, d), function(c, e)]
Вот что я получаю при использовании этого: TypeError: свойства «вызывающий», «вызываемый» и «аргументы» могут быть недоступны для функций строгого режима или объектов аргументов для их вызовов. Есть идеи, как это сделать в строгом режиме?
Я думаю, что следующий фрагмент кода может быть полезен:
window.fnPureLog = function(sStatement, anyVariable) {
if (arguments.length < 1) {
throw new Error('Arguments sStatement and anyVariable are expected');
}
if (typeof sStatement !== 'string') {
throw new Error('The type of sStatement is not match, please use string');
}
var oCallStackTrack = new Error();
console.info(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}
Выполните код:
window.fnPureLog = function(sStatement, anyVariable) {
if (arguments.length < 1) {
throw new Error('Arguments sStatement and anyVariable are expected');
}
if (typeof sStatement !== 'string') {
throw new Error('The type of sStatement is not match, please use string');
}
var oCallStackTrack = new Error();
console.info(oCallStackTrack.stack.replace('Error', 'Call Stack:'), '\n' + sStatement + ':', anyVariable);
}
function fnBsnCallStack1() {
fnPureLog('Stock Count', 100)
}
function fnBsnCallStack2() {
fnBsnCallStack1()
}
fnBsnCallStack2();
Журнал выглядит так:
Call Stack:
at window.fnPureLog (<anonymous>:8:27)
at fnBsnCallStack1 (<anonymous>:13:5)
at fnBsnCallStack2 (<anonymous>:17:5)
at <anonymous>:20:1
Stock Count: 100
Это ОЧЕНЬ ПОЛЕЗНО, потому что (во всяком случае в Chrome) сброс нового объекта Error () без изменений показывает информацию о файле / строке ИСТОЧНИКА (например, информацию о TypeScript). Однако ПОСЛЕ замены вы получите ФАКТИЧЕСКУЮ перенесенную информацию JavaScript. Понятия не имею, почему это происходит при простой замене строки, но это чистая случайность. Кроме того, с транспилированным кодом он показывает фактический URL-адрес, с которого был получен код, а не только имя модуля. Извлечение третьей строки вывода в любом случае может определить местоположение вызывающего абонента либо в исходном исходном коде, либо в перенесенном JavaScript.
Оба ответ Хейстюарта и JiarongWu ответ упомянули, что объект Error имеет доступ к stack.
Вот пример:
function main() {
Hello();
}
function Hello() {
var stack = new Error().stack;
// N.B. stack === "Error\n at Hello ...\n at main ... \n...."
var m = stack.match(/.*?Hello.*?\n(.*?)\n/);
if (m) {
var caller_name = m[1];
console.info("Caller is:", caller_name)
}
}
main();В разных браузерах стек отображается в разных строковых форматах:
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)
Большинство браузеров устанавливают стек с var stack = (new Error()).stack. В Internet Explorer стек будет неопределенным - для получения стека необходимо создать реальное исключение.
Вывод: с помощью stack в объекте Error можно определить, что «основной» - это вызывающий «Hello». Фактически, это будет работать в тех случаях, когда подход callee / caller не работает. Он также покажет вам контекст, то есть исходный файл и номер строки. Однако необходимы усилия, чтобы сделать решение кроссплатформенным.
Я бы сделал это:
function Hello() {
console.trace();
}
Это отлично работает! следует принять как правильный ответ, так как другие способы устарели \ больше не работают
caller запрещен в строгом режиме. Вот альтернатива с использованием (нестандартного) Стек Error.
Следующая функция, похоже, выполняет свою работу в Firefox 52 и Chrome 61-71, хотя ее реализация делает много предположений о формате ведения журнала двух браузеров и ее следует использовать с осторожностью, учитывая, что она генерирует исключение и, возможно, выполняет два регулярных выражения. сопоставления перед выполнением.
'use strict';
const fnNameMatcher = /([^(]+)@|at ([^(]+) \(/;
function fnName(str) {
const regexResult = fnNameMatcher.exec(str);
return regexResult[1] || regexResult[2];
}
function log(...messages) {
const logLines = (new Error().stack).split('\n');
const callerName = fnName(logLines[1]);
if (callerName !== null) {
if (callerName !== 'log') {
console.info(callerName, 'called log with:', ...messages);
} else {
console.info(fnName(logLines[2]), 'called log with:', ...messages);
}
} else {
console.info(...messages);
}
}
function foo() {
log('hi', 'there');
}
(function main() {
foo();
}());Это невероятно и ужасно.
Я получил "foo call with: hi there", но фу не был вызван с "hi there", журнал был вызван с "hi there"
Правильно, в грамматике сообщения об ошибке был "неуместный модификатор". Это означало, что «журнал был вызван из функции f, он хотел напечатать сообщение X», но как можно более кратко.
Просто запишите свой стек ошибок в консоль. Затем вы можете узнать, как вас зовут
const hello = () => {
console.info(new Error('I was called').stack)
}
const sello = () => {
hello()
}
sello()Поскольку ни один из предыдущих ответов не работает так, как я искал (получение только последнего вызывающего функцию, а не функцию в виде строки или стека вызовов), я публикую свое решение здесь для таких, как я, и надеюсь, что это сработает для них:
function getCallerName(func)
{
if (!func) return "anonymous";
let caller = func.caller;
if (!caller) return "anonymous";
caller = caller.toString();
if (!caller.trim().startsWith("function")) return "anonymous";
return caller.substring(0, caller.indexOf("(")).replace("function","");
}
// Example of how to use "getCallerName" function
function Hello(){
console.info("ex1 => " + getCallerName(Hello));
}
function Main(){
Hello();
// another example
console.info("ex3 => " + getCallerName(Main));
}
Main();И в ES6, и в строгом режиме используйте следующее, чтобы получить функцию вызывающего абонента
console.info((new Error()).stack.split("\n")[2].trim().split(" ")[1])
Обратите внимание, что приведенная выше строка вызовет исключение, если нет вызывающей стороны или нет предыдущего стека. Используйте соответственно.
Чтобы получить вызываемого (текущее имя функции), используйте:
console.info((new Error()).stack.split("\n")[1].trim().split(" ")[1])
Обратите внимание, что вы не можете использовать Function.caller в Node.js, вместо этого используйте пакет идентификатор вызывающего абонента. Например:
var callerId = require('caller-id');
function foo() {
bar();
}
function bar() {
var caller = callerId.getData();
/*
caller = {
typeName: 'Object',
functionName: 'foo',
filePath: '/path/of/this/file.js',
lineNumber: 5,
topLevelFlag: true,
nativeFlag: false,
evalFlag: false
}
*/
}
У меня отлично работает, и вы можете выбрать, на сколько вы хотите вернуться в функциях:
function getCaller(functionBack= 0) {
const back = functionBack * 2;
const stack = new Error().stack.split('at ');
const stackIndex = stack[3 + back].includes('C:') ? (3 + back) : (4 + back);
const isAsync = stack[stackIndex].includes('async');
let result;
if (isAsync)
result = stack[stackIndex].split(' ')[1].split(' ')[0];
else
result = stack[stackIndex].split(' ')[0];
return result;
}
Я надеюсь, что это просто поможет вам в отладке. Изменение поведения в зависимости от вызывающего - плохая идея.