2009-12-20 9 views
8

Sto cercando di ottenere il nome della funzione attualmente in esecuzione. Da quello che ho letto, questo dovrebbe essere possibile utilizzando:javascript - arguments.callee.toString() e arguments.callee.name non restituisce il nome della funzione

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

Tuttavia, quando ho eseguito questo in Firefox e Safari (versioni più recenti su Mac) il nome non viene restituito.

console.log (arguments.callee) restituisce l'origine della funzione, ma non il nome assegnato. arguments.callee.name restituisce una stringa vuota.

mio codice di esempio è il seguente:

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

Posso chiedere, perché vuoi/devi farlo? – James

+0

Yah. Quindi sto lavorando a un progetto per animali domestici che prevede il concatenamento di funzioni. Ho circa 50 diverse funzioni che eseguono tutti lo stesso codice, tranne per il fatto che una particolare variabile in esse è definita come lo stesso nome della funzione. Voglio ridurre tutta la duplicazione a una singola funzione che rileva il nome della funzione chiamante e usa quel nome come variabile attualmente codificata. Con questo metodo, posso definire tutte le mie funzioni in una singola riga. – Geuis

+2

Le funzioni di '' toString() 'come questo (ovvero la funzione" decompilazione ") hanno le sue verruche. Vedi http://perfectionkills.com/those-tricky-functions/, http://perfectionkills.com/detecting-built-in-host-methods/, http://my.opera.com/hallvors/blog/show .dml/1665828 e http://my.opera.com/hallvors/blog/2007/07/07/prototype-findorstore-considered-harmful –

risposta

7

Gli hack tipici arguments.callee non funzionano qui perché quello che hai fatto viene assegnato un funzione anonima come valore per la chiave 'testfunc' dell'oggetto. In questo caso la pirateria anche di peggio, ma si può fare, come segue:

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

È dichiarata una funzione anonima con

function(){ 

Si dovrebbe dichiareremo come

function testfunc(){ 

per ottenere il nome stampato.

+5

Si tenga presente che le espressioni di funzione denominate (che è ciò che si suggerisce) si comportano in modo strano in IE. Vedi http://yura.thinkweb2.com/named-function-expressions/ –

+0

@ Tim.Down buon punto e lettura interessante. –

+0

Per chiarire: nel caso dello stile oggetto sopra quello sarebbe '{testfunc: function testfunc() {...'. Questo è utile anche nel debugging delle cose nel browser, aiuta il debugger a capire in quale funzione hai problemi. – clacke

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

Che cosa è con il backslash prima [? Non penso che tu voglia una parentesi quadra letterale qui. Senza di ciò dovrebbe funzionare.

Sebbene mi piacerebbe fortemente consigliare contro qualsiasi cosa fare con il nome della funzione di sniffing o in particolare la funzione di annusata del chiamante. Quasi tutto ciò che potresti fare usando questi orribili hack sarà fatto meglio usando una combinazione di chiusure e ricerche.

0

Prima di tutto, la funzione non ha un nome. Il nome della funzione è ciò che inserisci tra function e l'elenco degli argomenti (...). Ecco come ottenere il nome di una funzione (non utilizzare la proprietà name, in quanto può essere modificato):

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

"non utilizzare la proprietà name, in quanto può essere modificata" - beh, è ​​possibile modificare anche il metodo toString() ... –

0

ho scoperto che se semplicemente accede l'oggetto funzione, in questo modo:

console.log(arguments.callee) 

o

console.debug(arguments.callee) 

che si ottiene semplicemente il nome della funzione nel log della console con alcune opzioni.

3

su Firefox 3.5, Safari 5 e Chrome 6.0 è possibile utilizzare:

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

myFunctionName(); 

È inoltre possibile ottenere la funzione che ha chiamato quella corrente utilizzando arguments.callee.caller.

2

Penso che ci sia una soluzione molto più pulita ed elegante per tutto questo.Supponendo che la funzione sia membro di un oggetto di livello superiore — e questo sarà sempre il caso, anche se il proprietario della funzione è "finestra" o qualche altro oggetto globale, possiamo accedere all'oggetto globale tramite la parola chiave, possiamo accedere alla funzione stessa tramite arguments.callee e possiamo accedere a tutti i nomi oggetto (funzione) del genitore tramite per (var o in questo), quindi dovresti essere in grado di ottenere le informazioni desiderate abbastanza facilmente come .. .

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

che dovrebbe essere robusto ed evitare eventuali comportamenti strani del browser IE accedere alle funzioni di nome, ecc

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

Aggiungere una descrizione della risposta ! – bahrep

Problemi correlati