2015-04-11 12 views
17

E 'possibile vedere il chiamato/chiamante di una funzione quando use strict è abilitato?Come si rileva la funzione chiamante in JavaScript quando è abilitato l'uso strict?

'use strict'; 
 

 
function jamie(){ 
 
    console.info(arguments.callee.caller.name); 
 
    //this will output the below error 
 
    //uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them 
 
}; 
 

 
function jiminyCricket(){ 
 
    jamie(); 
 
} 
 

 
jiminyCricket();

+2

In generale (con * pochissime * eccezioni) se si vuole farlo, si sta facendo qualcosa di sbagliato. Cerca di spiegare il * vero problema * che vuoi risolvere con questo codice. – zerkms

+2

Non c'è alternativa. Il modo consigliato è usare il nome della funzione direttamente come 'jamie.name // jamie'. Ma i nomi delle funzioni sono spesso irrilevanti, a parte il debugging, non fanno alcuna differenza nel tuo codice e fare affidamento su questa funzionalità per qualcosa di diverso dalla ricorsione è di solito un problema XY. – elclanrs

+0

Per essere onesti, non c'è alcun problema reale con il mio codice, ma ho una funzione alias di 'console.info' quindi' c = console.info' essenzialmente. Quindi, quando consolo qualcosa con detta funzione, mostra semplicemente nella console che proviene dallo stesso posto ogni volta. volevo produrre quale funzione lo chiamava. Solo per il fatto che io sia pigro e figo tutto in uno: D –

risposta

23

Per quello che vale, sono d'accordo con le osservazioni di cui sopra. Per qualsiasi problema tu stia cercando di risolvere, di solito ci sono soluzioni migliori.

Tuttavia, solo a scopo illustrativo, ecco uno (molto brutta) Soluzione:

'use strict' 
 

 
function jamie(){ 
 
var callerName; 
 
try { throw new Error(); } 
 
catch (e) { 
 
    var re = /(\w+)@|at (\w+) \(/g, st = e.stack, m; 
 
    re.exec(st), m = re.exec(st); 
 
    callerName = m[1] || m[2]; 
 
} 
 
console.log(callerName); 
 
}; 
 

 
function jiminyCricket(){ 
 
    jamie(); 
 
} 
 

 
jiminyCricket(); // jiminyCricket

Ho provato solo questo in Chrome, Firefox e IE11, così il vostro il chilometraggio può variare.

+0

ha una grande idea. Lanciare un errore Non è davvero un grosso problema in quanto tale. Sarebbe bello sapere da dove proviene il console.log. Non vedo questo come un problema? –

+1

Questo ha funzionato bene.Abbiamo dovuto utilizzare la versione throw invece della soluzione di @ inetphantom perché un motore JavaScript incorporato con cui abbiamo dovuto lavorare non popolava Error(). Stack fino a quando non è stato lanciato. – RomSteady

+0

Ciao, c'è un modo per ottenere i parametri della funzione chiamante? – easa

18

Si prega di notare che questo non dovrebbe essere utilizzato a fini produttivi. Questa è una brutta soluzione, che può essere utile per il debug, ma se hai bisogno di qualcosa dal chiamante, passala come argomento o salvala in una variabile accessibile.

La versione breve di risposta @pswg (senza gettare un errore, basta istanziare uno):

let re = /([^(]+)@|at ([^(]+) \(/g; 
    let aRegexResult = re.exec(new Error().stack); 
    sCallerName = aRegexResult[1] || aRegexResult[2]; 

completa Snippet:

'use strict' 
 

 
function jamie(){ 
 
    var sCallerName; 
 
    { 
 
     let re = /([^(]+)@|at ([^(]+) \(/g; 
 
     let aRegexResult = re.exec(new Error().stack); 
 
     sCallerName = aRegexResult[1] || aRegexResult[2]; 
 
    } 
 
    console.log(sCallerName); 
 
}; 
 

 
function jiminyCricket(){ 
 
    jamie(); 
 
}; 
 

 
jiminyCricket(); // jiminyCricket

+0

La regex che corrisponde al nome nello stack dovrebbe probabilmente essere '([^ (] +)' invece di '(\ w +)' perché gli spazi e la punteggiatura sono comuni – maffews

1

Non ha funzionato per me Ecco quello che finalmente faccio, nel caso in cui aiuti qualcuno

function callerName() { 
    try { 
    throw new Error(); 
    } 
    catch (e) { 
    try { 
     return e.stack.split('at ')[3].split(' ')[0]; 
    } catch (e) { 
     return ''; 
    } 
    } 

} 
function currentFunction(){ 
    let whoCallMe = callerName(); 
    console.log(whoCallMe); 
} 
+0

Cany ou per favore spiega perché questo ha funzionato per te e l'altro soluzioni non ha funzionato? –

+0

Ho avuto qualcosa di simile su un indiceRegexResult [1] nell'intervallo – Benamar

+0

l'indice aregexResult [1] fuori intervallo è perché i nomi nello stack di chiamate che non corrispondono a '\ w +' vengono saltati. 'Invece [^ (] +' – maffews

Problemi correlati