2009-12-20 14 views
8

Estoy tratando de obtener el nombre de la función que se está ejecutando actualmente. Por lo que he leído, esto debería ser posible usando:javascript - arguments.callee.toString() y arguments.callee.name no devuelve el nombre de función

(arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/) 

Sin embargo, cuando ejecuto esto en Firefox y Safari (últimas versiones en Mac) no se devuelve el nombre.

console.log (arguments.callee) devuelve el origen de la función, pero no el nombre asignado. arguments.callee.name devuelve una cadena vacía.

Mi código de ejemplo es el siguiente:

var testobj = { 
    testfunc: function(){ 
     console.log((arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/)); 
    } 
} 
testobj.testfunc(); 
+0

¿Puedo preguntar, por qué quiere/necesita hacer esto? – James

+0

Yah. Así que estoy trabajando en un proyecto de mascotas que implica el encadenamiento de funciones. Tengo aproximadamente 50 funciones diferentes que ejecutan el mismo código, excepto que una variable particular en ellas se define como el mismo nombre de la función. Quiero reducir toda la duplicación a una sola función que detecta el nombre de la función de llamada y utiliza ese nombre como la variable que está codificada actualmente. Con este método, puedo definir todas mis funciones en una sola línea. – Geuis

+2

'toString()' funciones de ing como este (alias función "descompilación") tiene sus verrugas. Consulte http://perfectionkills.com/those-tricky-functions/, http://perfectionkills.com/detecting-built-in-host-methods/, http://my.opera.com/hallvors/blog/show .dml/1665828 y http://my.opera.com/hallvors/blog/2007/07/07/prototype-findorstore-considered-harmful –

Respuesta

7

Los cortes típicos arguments.callee no funcionan aquí porque lo que has hecho se le asigna una función anónima como el valor de la clave 'testfunc' del objeto. En este caso, la piratería incluso empeora, pero se puede hacer, de la siguiente manera:

var testobj = { 
    testfunc: function(){ 
     for (var attr in testobj) { 
       if (testobj[attr] == arguments.callee.toString()) { 
        alert(attr); 
        break; 
       } 
      } 
    } 
} 
testobj.testfunc(); 
10

Se ha declarado en una función anónima con

function(){ 

Usted debe declarar como

function testfunc(){ 

para obtener el nombre impreso.

+5

Tenga en cuenta que las expresiones de funciones nombradas (que es lo que está sugiriendo) se comportan de forma extraña en IE. Consulte http://yura.thinkweb2.com/named-function-expressions/ –

+0

@ Tim.Down punto bueno y lectura interesante. –

+0

Para aclarar: en el caso del estilo de objeto anterior, sería '{testfunc: function testfunc() {...'. También es bueno hacerlo cuando depura cosas en el navegador, ayuda a que el depurador lo ayude a ver en qué función tiene problemas. – clacke

2
/function\s+(\[^\s\(]+)/ 

¿Qué pasa con la barra invertida antes de [? No creo que quieras un corchete literal aquí. Sin eso debería funcionar.

aunque me fuertemente recomiendan en contra de nada que ver con la inhalación nombre de la función o, especialmente, olfateando la función de llamada. Casi cualquier cosa que hagas con estos espantosos hacks se hará mejor usando una combinación de cierres y búsquedas.

0

En primer lugar, la función no tiene un nombre. El nombre de la función es lo que pones entre function y la lista de argumentos (...). Aquí es cómo conseguir el nombre de una función (no utilice la propiedad name, ya que puede ser cambiado):

var fName = arguments.callee.toString(0).match(
    /^function\s*(?:\s+([\w\$]*))?\s*\(/ 
); 
fName = (fName ? fName[1] : ""); 
+0

"no use la propiedad del nombre, ya que se puede cambiar" - bueno, también se puede cambiar el método toString() ... –

0

He descubierto que si simplemente registrar el objeto función, así:

console.log(arguments.callee) 

o

console.debug(arguments.callee) 

que simplemente obtiene el nombre de la función en el registro de la consola con algunas opciones.

3

en Firefox 3.5, Safari 5 y Chrome 6.0 se puede utilizar:

function myFunctionName() { 
alert("Name is " + arguments.callee.name); 
} 

myFunctionName(); 

También puede obtener la función que llamó la actual usando arguments.callee.caller.

2

Creo que hay una solución mucho más limpia y elegante para todo esto.Suponiendo que la función es miembro de algún objeto de nivel superior — y ese siempre será el caso, incluso si el propietario de la función es "ventana" u otro objeto global, podemos acceder al objeto global a través de esta palabra clave, podemos acceder a la función a través de arguments.callee y podemos acceder a todos los nombres de objeto (función) del padre vía para (var o en esto), por lo que debería poder obtener la información deseada con bastante facilidad. .

returnMyName = function() { 
    for (var o in this) { 
    if (arguments.callee===this[o]) return o; 
    } 
}; 

Eso debe ser robusto y evitar cualquier comportamiento extraño del navegador IE para acceder a funciones con nombre, etc.

1
Function.prototype.getName = function(fn) { 
    if(Function.name || Function.prototype.name) return this.name; 
    return this.toString().match(/^function\s+(\w+)\s*\(/)[1]; 
}; 
+0

Agregue una descripción de la respuesta ! – bahrep

Cuestiones relacionadas