Respuestas:
En ES5 y superior, no hay acceso a esa información.
En versiones anteriores de JS puede obtenerlo usando arguments.callee
.
Sin embargo, es posible que deba analizar el nombre, ya que probablemente incluirá algo de basura adicional. Sin embargo, en algunas implementaciones simplemente puede obtener el nombre usando arguments.callee.name
.
Analizando:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
Fuente: Javascript: obtener el nombre de la función actual .
arguments.callee
no está permitido en modo estricto.
Para funciones no anónimas
function foo()
{
alert(arguments.callee.name)
}
Pero en caso de un controlador de errores, el resultado sería el nombre de la función del controlador de errores, ¿no?
Todo lo que necesitas es simple. Crear función:
function getFuncName() {
return getFuncName.caller.name
}
Después de eso, siempre que lo necesite, simplemente use:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
function getFuncName() { return getFuncName.name }
getFuncName
lugar del nombre de la persona que llama.
De acuerdo con MDN
Advertencia: La quinta edición de ECMAScript (ES5) prohíbe el uso de argumentos.callee () en modo estricto. Evite usar argumentos.callee () dando un nombre a las expresiones de función o utilice una declaración de función donde una función debe llamarse a sí misma.
Como se señaló, esto se aplica solo si su script usa "modo estricto". Esto es principalmente por razones de seguridad y lamentablemente actualmente no hay alternativa para esto.
Esto debería hacerlo:
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
Para la persona que llama, solo use caller.toString()
.
[
Esto tiene que ir en la categoría de "hacks más feos del mundo", pero aquí tienes.
Primero, imprimir el nombre de la función actual (como en las otras respuestas) parece tener un uso limitado para mí, ¡ya que ya sabes cuál es la función!
Sin embargo, averiguar el nombre de la función de llamada podría ser bastante útil para una función de rastreo. Esto es con una expresión regular, pero usar indexOf sería aproximadamente 3 veces más 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();
Aquí hay una manera que 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);
}
Luego en tus pruebas:
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);
});
});
Tenga en cuenta que la tercera prueba solo funcionará si la prueba se encuentra en / util / functions
La getMyName
función en el fragmento a continuación devuelve el nombre de la función de llamada. Es un truco y se basa en la no-estándar de función: Error.prototype.stack
. Tenga en cuenta que el formato de la cadena devuelta por Error.prototype.stack
se implementa de manera diferente en diferentes motores, por lo que esto probablemente no funcionará en todas partes:
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())
Acerca de otras soluciones: arguments.callee
no está permitido en modo estricto y noFunction.prototype.caller
es estándar y no está permitido en modo estricto .
Otro caso de uso podría ser un despachador de eventos vinculado en tiempo de ejecución:
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);
La ventaja aquí es que el despachador se puede reutilizar fácilmente y no tiene que recibir la cola de despacho como argumento, sino que viene implícito con el nombre de la invocación ...
Al final, el caso general presentado aquí sería "usar el nombre de la función como argumento para que no tenga que pasarlo explícitamente", y eso podría ser útil en muchos casos, como la devolución de llamada opcional jquery animate (), o en tiempos de espera / intervalos de devolución de llamada (es decir, solo pasa un NOMBRE de función).
El nombre de la función actual y cómo se puede obtener parece haber cambiado en los últimos 10 años, ya que se hizo esta pregunta.
Ahora, al no ser un desarrollador web profesional que conozca todas las historias de todos los navegadores que hayan existido, así es como funciona para mí en un navegador Chrome 2019:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
Algunas de las otras respuestas se encontraron con algunos errores de Chrome sobre el código JavaScript estricto y otras cosas.
Dado que ha escrito una función llamada foo
y sabe que es así, myfile.js
¿por qué necesita obtener esta información dinámicamente?
Dicho esto, puede usar arguments.callee.toString()
dentro de la función (esta es una representación de cadena de toda la función) y expresar el valor del nombre de la función.
Aquí hay una función que escupirá su propio nombre:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
Una combinación de las pocas respuestas que he visto aquí. (Probado en 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);
}
Llamar a randomFunction () alertará a una cadena que contiene el nombre de la función.
Demostración de JS Fiddle: http://jsfiddle.net/mjgqfhbe/
Puede encontrar una respuesta actualizada a esto en esta respuesta: https://stackoverflow.com/a/2161470/632495
y, si no tiene ganas de hacer clic:
function test() {
var z = arguments.callee.name;
console.log(z);
}
La información es actual en el año 2016.
Resultado en la 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 en el 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 en el 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
No funciona en Firefox. No probado en el IE y The Edge.
Resultado en el NodeJS
> var func11 = function(){
... console.log('Function name:', arguments.callee.name)
... }; func11();
Function name: func11
Resultado en el Chrome
var func11 = function(){
console.log('Function name:', arguments.callee.name)
}; func11();
Function name: func11
No funciona en Firefox, Opera. No probado en el IE y The Edge.
Notas:
~ $ 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
})();
Variación mecanografiada:
function f1() {}
function f2(f:Function) {
console.log(f.name);
}
f2(f1); //Logs f1
Nota solo disponible en motores compatibles con ES6 / ES2015. Para más ver
Aquí hay una línea:
arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '')
Me gusta esto:
function logChanges() {
let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '');
console.log(whoami + ': just getting started.');
}
Esta es una variante de la respuesta de Igor Ostroumov :
Si desea utilizarlo como valor predeterminado para un parámetro, debe considerar una llamada de segundo nivel a 'llamante':
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
Esto permitiría dinámicamente una implementación reutilizable en múltiples funciones.
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
function bar(myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(myFunctionName);
}
// pops-up "foo"
function foo()
{
bar();
}
function crow()
{
bar();
}
foo();
crow();
Si también desea el nombre del archivo, aquí está esa solución usando la respuesta de F-3000 en otra pregunta:
function getCurrentFileName()
{
let currentFilePath = document.scripts[document.scripts.length-1].src
let fileName = currentFilePath.split('/').pop() // formatted to the OP's preference
return fileName
}
function bar(fileName = getCurrentFileName(), myFunctionName = getFunctionsNameThatCalledThisFunction())
{
alert(fileName + ' : ' + myFunctionName);
}
// or even better: "myfile.js : foo"
function foo()
{
bar();
}