- JavaScript | Как получить имя функции из тела функции при её вызове?
- Видеоролик
- Зачем нужно получать имя функции при её вызове?
- Информационные ссылки
- Вам также может понравиться
- JavaScript | Как создать объект DOM-документа из строки с HTML-разметкой на клиенте?
- JavaScript | Как узнать длину массива без пустых элементов?
- JavaScript | Как сохранить строку (данные) в файл на клиенте (браузере)?
- JavaScript | Как выполнение функции может не дойти до return?
- Могу ли я получить имя запущенной функции в JavaScript?
JavaScript | Как получить имя функции из тела функции при её вызове?
Прежде всего нужно помнить, что функции в JavaScript могут быть двух видов:
- Обычные функции (нормальные, которые оформляются через ключевое слово function )
- Стрелочные функции (с урезанными возможностями, которые оформляются в виде ()=>1 )
В стрелочных функциях не определяются локальные привязки для arguments , super , this , or new.target .
Для получения имени функции нужно обращаться к объекту arguments:
return arguments . callee . name
Выражение « arguments.callee.name » вернёт нам строку ‘ vasya ‘.
Видеоролик
Зачем нужно получать имя функции при её вызове?
Предположим у нас имеется функция, которая выполняет полезные действия.
Её вызов с параметрами вернёт нам число 6 .
Но мы в любой момент можем получить её имя и вывести его в консоль.
Мы делаем это для того, чтобы иметь возможность записать в журнал вызовов, последовательность вызываемых функций. Если вы работаете на серверной стороне и используете для этого NodeJS, тогда в файл будут писаться эти сообщения.
И для этого нам не нужно каждый раз писать « console.log(`Вызвана функция А`) » или « console.log(`Вызвана функция Б`) «.
Мы можем писать общую команду для логирования — «console.log(`Вызвана функция $< arguments.callee.name >`)».
Такой подход позволяет сократить упоминания самой функции в коде. Если бы мы использовали выражение « console.log(`Вызвана функция sumABC()`) «, то в нашем рабочем файле было бы уже три места с таким упоминанием. Если код большой и функция вызывается в разных местах, то это очень неудобно — будешь отвлекаться.
Информационные ссылки
Вам также может понравиться
JavaScript | Как создать объект DOM-документа из строки с HTML-разметкой на клиенте?
Способ № 1 — Через интерфейс DOMParser Стандарт DOM Parsing and Serialization — https://www.w3.org/TR/DOM-Parsing/ описывает интерфейс DOMParser, у которого есть метод parseFromString(str, […]
JavaScript | Как узнать длину массива без пустых элементов?
Есть массив с пустыми элементами (empty): var massiv = [1,,2. 3. 4] Задача Мы хотим узнать длину этого массива без пустых элементов. В […]
JavaScript | Как сохранить строку (данные) в файл на клиенте (браузере)?
Задача примитивно простая — нужно сохранить строку из браузера в какой-нибудь файл на компьютере или ноутбуке. Строка представляет собой полезные данные. Пусть […]
JavaScript | Как выполнение функции может не дойти до return?
Оператор return относится к операторам «внезапного завершения» функции. Это значит, что кроме return существуют другие операторы, которые могут внезапно завершить выполнение функции. […]
Могу ли я получить имя запущенной функции в JavaScript?
Вы можете получить его, используя arguments.callee . Возможно, вам придется разобрать это имя, поскольку оно, вероятно, включает в себя некоторые дополнительные нежелательные эффекты. Хотя в некоторых реализациях вы можете просто получить имя с помощью arguments.callee.name . Синтаксический:
На самом деле, на самом деле, уделяя больше внимания вашему вопросу, звучит так, будто вам захочется лишнего мусора 🙂
@Matt Matt — Если вы собираетесь использовать онлайн-источник, пожалуйста, укажите его. Ваш пример кода явно взят с tek-tips.com/viewthread.cfm?qid=1209619, и первоначальный автор несправедливо использует его, не отдавая должное.
@Andrew Андрей — Вы правы, я должен был это заявить. Это было быстрое копирование / вставка / очистка того, что я уже добавил в закладки, и упущение с моей стороны. Спасибо за добавление его в мой пост.
если вы используете литерал объекта для своих методов и не используете фактическое имя метода, то это не будет работать в качестве arguments.callee действует как анонимная функция, которая не будет содержать никакого имени функции. Вы должны убедиться, что вы добавили это имя функции дважды. Взгляните на этот пример jsfiddle : jsfiddle.net/ncays . другая проблема, связанная с этим, заключается в том, что arguments.callee не допускается в строгом режиме.
Но в случае обработчика ошибки результат будет именем функции обработчика ошибок, не так ли?
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/); alert(fn[1]);
Для вызывающего абонента просто используйте caller.toString() .
Это сработало для меня, но я думаю, что в вашем регулярном выражении есть опечатка. Я должен был убрать обратную косую черту до того, как [
@declan: да, вы правы. Удивительно, что никто не указал, что за почти 3 года этот ответ был здесь 🙂
Предупреждение: Пятое издание ECMAScript (ES5) запрещает использование arguments.callee() в строгом режиме. Избегайте использования arguments.callee() путем предоставления выражений функции имени или использования объявления функции, где функция должна вызывать себя.
Как уже отмечалось, применяется только, если ваш script использует «строгий режим». Это в основном по соображениям безопасности и, к сожалению, в настоящее время нет альтернативы для этого.
Это должно быть в категории «самых уродливых хаков в мире», но здесь вы идете.
Прежде всего, печать имени текущей функции (как и в других ответах), по-видимому, ограничена для меня, поскольку вы уже знаете, что это за функция!
Однако обнаружение имени вызывающей функции может быть очень полезно для функции трассировки. Это с регулярным выражением, но с использованием indexOf будет примерно в 3 раза быстрее:
function getFunctionName() < var re = /function (.*?)\(/ var s = getFunctionName.caller.toString(); var m = re.exec( s ) return m[1]; >function me() < console.log( getFunctionName() ); >me();
классное решение, но FYI Function # caller не является стандартным developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Знание имени текущей функции может быть важно, если эта функция создается динамически из базы данных и нуждается в контекстной информации внутри функции, которая связана с именем функции.
export function getFunctionCallerName () < // gets the text between whitespace for second part of stacktrace return (new Error()).stack.match(/at (\S+)/g)[1].slice(3); >
import < expect >from 'chai'; import < getFunctionCallerName >from '../../../lib/util/functions'; describe('Testing caller name', () => < it('should return the name of the function', () => < function getThisName()< return getFunctionCallerName(); >const functionName = getThisName(); expect(functionName).to.equal('getThisName'); >); it('should work with an anonymous function', () => < const anonymousFn = function ()< return getFunctionCallerName(); >; const functionName = anonymousFn(); expect(functionName).to.equal('anonymousFn'); >); it('should work with an anonymous function', () => < const fnName = (function ()< return getFunctionCallerName(); >)(); expect(/\/util\/functions\.js/.test(fnName)).to.eql(true); >); >);
Обратите внимание, что третий тест будет работать, только если тест находится в/util/functions
Другим вариантом использования может быть диспетчер событий, связанный во время выполнения:
MyClass = function () < this.events = <>; // Fire up an event (most probably from inside an instance method) this.OnFirstRun(); // Fire up other event (most probably from inside an instance method) this.OnLastRun(); > MyClass.prototype.dispatchEvents = function () < var EventStack=this.events[GetFunctionName()], i=EventStack.length-1; do EventStack[i](); while (i--); >MyClass.prototype.setEvent = function (event, callback) < this.events[event] = []; this.events[event].push(callback); this["On"+event] = this.dispatchEvents; >MyObject = new MyClass(); MyObject.setEvent ("FirstRun", somecallback); MyObject.setEvent ("FirstRun", someothercallback); MyObject.setEvent ("LastRun", yetanothercallback);
Преимущество в том, что диспетчер может быть легко повторно использован и не должен получать очередь отправки в качестве аргумента, вместо этого он подразумевается с именем вызова.
В итоге общий случай, представленный здесь, будет «использовать имя функции в качестве аргумента, чтобы вам не нужно было передавать его явно», и это может быть полезно во многих случаях, например jquery animate() необязательный обратный вызов или обратные вызовы с тайм-аутами/интервалами (т.е. вы передаете только имя пользователя funcion).
Функция getMyName в фрагменте ниже возвращает имя вызывающей функции. Это взломать и полагается на нестандартную функцию: Error.prototype.stack .
function getMyName() < var e = new Error('dummy'); var stack = e.stack .split('\n')[2] // " at functionName ( . " =>"functionName" .replace(/^\s+at\s+(.+?)\s.+/g, '$1' ); return stack > function foo() < return getMyName() >function bar() < return foo() >console.log(bar())
О других решениях: arguments.callee не работает в строгом режиме, а Function.prototype.caller — нестандартный, но имеет лучшую поддержку, чем Error.prototype.stack .