Posso obter o nome da function atualmente em execução em JavaScript?

É possível fazer isso:

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

Eu tenho as estruturas Dojo e jQuery na minha pilha, então, se qualquer uma delas facilitar, elas estarão disponíveis.

Você deve poder obtê-lo usando arguments.callee .

Você pode ter que analisar o nome, pois provavelmente includeá algum lixo extra. Embora, em algumas implementações, você possa simplesmente obter o nome usando arguments.callee.name .

Análise:

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

Fonte: Javascript – obtenha o nome da function atual .

Para funções não anônimas

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

Mas no caso de um manipulador de erro, o resultado seria o nome da function de tratamento de erros, não seria?

Isso deve servir:

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

Para o chamador, apenas use o caller.toString() .

De acordo com o MDN

Aviso: A quinta edição do ECMAScript (ES5) proíbe o uso de arguments.callee () no modo estrito. Evite usar arguments.callee (), dando um nome a expressões de function, ou use uma declaração de function onde uma function deve se chamar.

Como observado, isso se aplica somente se o seu script usar o “modo estrito”. Isto é principalmente por razões de segurança e, infelizmente, atualmente não há alternativa para isso.

Isso tem que ir na categoria de “hacks mais feios do mundo”, mas aqui vai você.

Primeiro, imprimir o nome da function atual (como nas outras respostas) parece ter uso limitado para mim, já que você já sabe qual é a function!

No entanto, descobrir o nome da function de chamada pode ser bastante útil para uma function de rastreamento. Isto é com um regexp, mas usando indexOf seria cerca de 3x mais rápido:

 function getFunctionName() { var re = /function (.*?)\(/ var s = getFunctionName.caller.toString(); var m = re.exec( s ) return m[1]; } function me() { console.log( getFunctionName() ); } me(); 

Aqui está uma maneira que vai funcionar:

 export function getFunctionCallerName (){ // gets the text between whitespace for second part of stacktrace return (new Error()).stack.match(/at (\S+)/g)[1].slice(3); } 

Então nos seus testes:

 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); }); }); 

Observe que o terceiro teste só funcionará se o teste estiver localizado em / util / functions

Tudo o que você precisa é simples. Criar function:

 function getFuncName() { return getFuncName.caller.name } 

Depois disso, sempre que precisar, basta usar:

 function foo() { console.log(getFuncName()) } foo() // Logs: "foo" 

Outro caso de uso pode ser um dispatcher de evento ligado em tempo de execução:

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

A vantagem aqui é que o dispatcher pode ser facilmente reutilizado e não precisa receber a fila de dispatch como um argumento, em vez disso vem implícito com o nome da invocação …

No final, o caso geral apresentado aqui seria “usando o nome da function como um argumento para que você não precise passá-lo explicitamente”, e isso pode ser útil em muitos casos, como o retorno de chamada opcional jquery animate () ou em tempos de espera / intervalos retornos de chamada, (ou seja, você só passa um NAME funcion).

A function getMyName no snippet abaixo retorna o nome da function de chamada. É um hack e depende de um recurso não padrão : 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()) 

Desde que você escreveu uma function chamada foo e você sabe que está em myfile.js por que você precisa obter essas informações dinamicamente?

Dito isto, você pode usar arguments.callee.toString() dentro da function (isto é uma representação de string da function inteira) e regexar o valor do nome da function.

Aqui está uma function que vai cuspir seu próprio nome:

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

Uma resposta atualizada para isso pode ser encontrada nesta resposta: https://stackoverflow.com/a/2161470/632495

e, se você não sentir vontade de clicar:

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

Uma combinação das poucas respostas que vi aqui. (Testado em 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); } 

Chamar randomFunction () alertará uma string que contém o nome da function.

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

Aqui está um forro:

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

Como isso:

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

A informação é atual no ano de 2016.


Resultados para declaração de function

Resultado no 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 

Resultado no 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 

Resultado no 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 

Não funciona no Firefox. Não testado no IE e no Edge.


Resultados para expressões de function

Resultado no NodeJS

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

Resultado no Chrome

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

Não funciona no Firefox, Opera. Não testado no IE e no Edge.

Notas:

  1. Função anônima não faz sentido para verificar.
  2. Ambiente de teste

 ~ $ 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 
 (function f() { console.log(f.name); //logs f })(); 

Variação datilografada:

 function f1() {} function f2(f:Function) { console.log(f.name); } f2(f1); //Logs f1 

Nota apenas disponível em motores compatíveis com ES6 / ES2015. Para mais veja

Experimentar:

 alert(arguments.callee.toString()); 

A resposta é curta: alert(arguments.callee.name);