Могу ли я получить имя текущей функции в JavaScript?

Возможно ли это сделать:

myfile.js:
function foo() {
    alert(<my-function-name>);
    // pops-up "foo"
    // or even better: "myfile.js : foo"
}

В моем стеке есть фреймы Dojo и jQuery, поэтому, если любой из них упростит их, они будут доступны.

Ответ 1

Вы можете получить его, используя arguments.callee.

Возможно, вам придется разобрать это имя, поскольку оно, вероятно, включает в себя некоторые дополнительные нежелательные эффекты. Хотя в некоторых реализациях вы можете просто получить имя с помощью arguments.callee.name.

Синтаксический:

function DisplayMyName() 
{
   var myName = arguments.callee.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));

   alert(myName);
}

Источник: Javascript - получить текущее имя функции.

Ответ 2

Для неанонимных функций

function foo()
{ 
    alert(arguments.callee.name)
}

Но в случае обработчика ошибки результат будет именем функции обработчика ошибок, не так ли?

Ответ 3

Это должно сделать это:

var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);

Для вызывающего абонента просто используйте caller.toString().

Ответ 4

Это должно быть в категории "самых уродливых хаков в мире", но здесь вы идете.

Прежде всего, печать имени текущей функции (как и в других ответах), по-видимому, ограничена для меня, поскольку вы уже знаете, что это за функция!

Однако обнаружение имени вызывающей функции может быть очень полезно для функции трассировки. Это с регулярным выражением, но с использованием 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();

Ответ 5

Согласно MDN

Предупреждение: Пятое издание ECMAScript (ES5) запрещает использование arguments.callee() в строгом режиме. Избегайте использования arguments.callee() путем предоставления выражений функции имени или использования объявления функции, где функция должна вызывать себя.

Как уже отмечалось, применяется только, если ваш script использует "строгий режим". Это в основном по соображениям безопасности и, к сожалению, в настоящее время нет альтернативы для этого.

Ответ 6

Другим вариантом использования может быть диспетчер событий, связанный во время выполнения:

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).

Ответ 7

Вот как это работает:

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

Ответ 8

Поскольку вы написали функцию с именем foo и знаете, что она находится в myfile.js, почему вам нужно динамически получать эту информацию?

Сказав это, вы можете использовать arguments.callee.toString() внутри функции (это строковое представление всей функции) и повторно вывести значение имени функции.

Вот функция, которая выплюнет свое имя:

function foo() {
    re = /^function\s+([^(]+)/
    alert(re.exec(arguments.callee.toString())[1]);             
}

Ответ 9

Обновленный ответ на этот вопрос можно найти в этом ответе: fooobar.com/questions/47143/...

и, если вам не хочется нажимать:

function test() {
  var z = arguments.callee.name;
  console.log(z);
}

Ответ 10

Функция 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())

Ответ 11

Комбинация нескольких ответов, которые я видел здесь. (Протестировано в FF, Chrome, IE11)

function functionName() 
{
   var myName = functionName.caller.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));
   return myName;
}

function randomFunction(){
    var proof = "This proves that I found the name '" + functionName() + "'";
    alert(proof);
}

Вызов randomFunction() будет вызывать строку, содержащую имя функции.

JS Fiddle Demo: http://jsfiddle.net/mjgqfhbe/

Ответ 12

Вот один лайнер:

    arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')

Вот так:

    function logChanges() {
      let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
      console.log(whoami + ': just getting started.');
    }

Ответ 13

Информация актуальна в 2016 году.


Результаты для объявления функции

Результат в Opera

>>> (function func11 (){
...     console.log(
...         'Function name:',
...         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
... 
... (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name:, func11
Function name:, func12

Результат в Chrome

(function func11 (){
    console.log(
        'Function name:',
        arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
})();

(function func12 (){
    console.log('Function name:', arguments.callee.name)
})();
Function name: func11
Function name: func12

Результат в NodeJS

> (function func11 (){
...     console.log(
.....         'Function name:',
.....         arguments.callee.toString().match(/function\s+([_\w]+)/)[1])
... })();
Function name: func11
undefined
> (function func12 (){
...     console.log('Function name:', arguments.callee.name)
... })();
Function name: func12

Не работает в Firefox. Не проиндексирован в IE и Edge.


Результаты для выражений функций

Результат в NodeJS

> var func11 = function(){
...     console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11

Результат в Chrome

var func11 = function(){
    console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11

Не работает в Firefox, Opera. Не проиндексирован в IE и Edge.

Примечания:

  • Анонимная функция не имеет смысла проверять.
  • Условия тестирования

~ $ google-chrome --version
Google Chrome 53.0.2785.116           
~ $ opera --version
Opera 12.16 Build 1860 for Linux x86_64.
~ $ firefox --version
Mozilla Firefox 49.0
~ $ node
node    nodejs  
~ $ nodejs --version
v6.8.1
~ $ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Ответ 14

Try:

alert(arguments.callee.toString());

Ответ 15

Ответ короткий: alert(arguments.callee.name);