Wie bekomme ich den Namen der Funktion innerhalb dieser Funktion? [javascript]


Answers

ES6 (inspiriert von der Antwort von sendy halim unten):

myFunction.name

Erklärung zu MDN . Ab 2015 funktioniert in nodejs und allen gängigen Browsern außer IE.

Hinweis: Bei gebundenen Funktionen wird " bound <originalName> " angegeben. Sie müssen die "Grenze" entfernen, wenn Sie den ursprünglichen Namen erhalten möchten.

ES5 (inspiriert von Vlads Antwort):

Wenn Sie einen Verweis auf die Funktion haben, können Sie Folgendes tun:

function functionName( func )
{
    // Match:
    // - ^          the beginning of the string
    // - function   the word 'function'
    // - \s+        at least some white space
    // - ([\w\$]+)  capture one or more valid JavaScript identifier characters
    // - \s*        optionally followed by white space (in theory there won't be any here,
    //              so if performance is an issue this can be omitted[1]
    // - \(         followed by an opening brace
    //
    var result = /^function\s+([\w\$]+)\s*\(/.exec( func.toString() )

    return  result  ?  result[ 1 ]  :  '' // for an anonymous function there won't be a match
}
  • Ich habe hier keine Unit-Tests durchgeführt oder Implementierungsunterschiede verifiziert, aber im Prinzip sollte es funktionieren, wenn nicht einen Kommentar hinterlassen.
  • Hinweis: Funktioniert nicht an gebundenen Funktionen
  • Hinweis: caller und callee gelten als veraltet.

[1] Ich füge es hier ein, weil es legal ist und oft genug Syntax-Highlighting-Tools den Leerraum zwischen Funktionsnamen und Klammern nicht berücksichtigen. Auf der anderen Seite ist mir keine Implementierung von .toString () bekannt, die hier Leerraum enthält, weshalb Sie es auslassen können.

Als Antwort auf die ursprüngliche Frage würde ich parasitäre Vererbung fallen lassen und einige traditionelle OOP-Entwurfsmuster verwenden. Ich schrieb ein TidBits.OoJs, um bequem OOP-Code in JavaScript mit einem Feature-Set zu schreiben, das C ++ nachahmt (noch nicht abgeschlossen, aber meistens).

Ich sehe aus den Kommentaren, dass Sie es vermeiden möchten, Informationen parent Anforderungen an den Konstruktor weiterzuleiten. Ich muss zugeben, dass traditionelle Entwurfsmuster Sie nicht vor dem einen bewahren, da es im Allgemeinen als eine gute Sache angesehen wird, Ihre Abhängigkeiten offensichtlich und erzwungen zu machen.

Ich würde auch vorschlagen, von anonymen Funktionen weg zu steuern. Sie machen nur ein Debuggen und Profiling eines PITA, weil alles nur als "anonyme Funktion" erscheint und es keinen Vorteil für sie gibt, den ich kenne.

Question

Wie kann ich innerhalb dieser Funktion auf einen Funktionsnamen zugreifen?

// parasitic inheritance
var ns.parent.child = function() {
  var parent = new ns.parent();
  parent.newFunc = function() {

  }
  return parent;
}

var ns.parent = function() {
  // at this point, i want to know who the child is that called the parent
  // ie
}

var obj = new ns.parent.child();



Das könnte für Sie arbeiten:

function foo() { bar(); }

function bar() { console.log(bar.caller.name); }

running foo () gibt "foo" oder undefined aus, wenn Sie von einer anonymen Funktion aus anrufen.

Es funktioniert auch mit Konstruktoren, in diesem Fall würde es den Namen des aufrufenden Konstruktors (zB "Foo") ausgeben.

Mehr Infos hier: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller

Sie behaupten, es sei nicht der Standard, aber auch, dass es von allen gängigen Browsern unterstützt wird: Firefox, Safari, Chrome, Opera und IE.




Du kannst nicht. Funktionen haben keine Namen gemäß dem Standard (obwohl mozilla ein solches Attribut hat) - sie können nur Variablen mit Namen zugewiesen werden.

Auch dein Kommentar:

// access fully qualified name (ie "my.namespace.myFunc")

ist in der Funktion my.namespace.myFunc.getFn

Was Sie tun können, ist die Rückgabe des Konstruktors eines durch neue

So könnte man sagen

var obj = new my.namespace.myFunc();
console.info(obj.constructor); //my.namespace.myFunc



Sie könnten Function.name :

In den meisten Implementierungen von JavaScript können Sie, sobald Sie die Referenz Ihres Konstruktors im Gültigkeitsbereich haben, seinen Zeichenkettennamen von seiner Eigenschaft name (zB Function.name oder Object.constructor.name) abrufen.

Sie könnten Function.callee :

Die native arguments.caller Methode ist veraltet, aber die meisten Browser unterstützen Function.caller , wodurch das eigentliche aufrufende Objekt (sein Code-Rumpf) zurückgegeben wird: https://developer.mozilla.org/en-US/docs/Web/ JavaScript / Referenz / Global_Objects / Funktion / Aufrufer? Redirectlocale = de-DE & redirectslug = JavaScript% 2FReference% 2FGlobal_Objects% 2FFunction% 2Fcaller

Sie könnten eine Quellkarte erstellen :

Wenn Sie die Literalfunktions-Signatur (den "Namen") und nicht das Objekt selbst benötigen, müssen Sie möglicherweise auf etwas mehr angepasstes Verhalten zurückgreifen, z. B. eine Array-Referenz der API-String-Werte erstellen, die Sie benötigen. häufig zugreifen. Sie können sie zusammen mit Object.keys() und Ihrem Array von Strings Object.keys() oder in Mozillas Source-Maps-Bibliothek auf GitHub nachsehen, für größere Projekte: https://github.com/mozilla/source-map




als Teil von ECMAScript 6 Sie die Function.name Methode verwenden

function doSomething() {}

alert(doSomething.name); // alerts "doSomething"



Ich weiß, das ist eine alte Frage, aber in letzter Zeit habe ich ein ähnliches Problem gesehen, während ich versucht habe, einige der Methoden von React Component für Debugging-Zwecke zu dekorieren. Wie die Leute schon sagten, sind arguments.caller und arguments.callee im strikten Modus verboten, was wahrscheinlich standardmäßig durch React transpiling ermöglicht wird. Sie können es entweder deaktivieren oder ich konnte einen anderen Hack entwickeln, da in React alle Klassenfunktionen benannt sind, können Sie dies tatsächlich tun:

Component.prototype.componentWillMount = function componentWillMount() {
    console.log('Callee name: ', this.__proto__.constructor.toString().substr(0,30));
...
}



Ich hatte ein ähnliches Problem und habe es wie folgt gelöst:

Function.prototype.myname = function() {
   return this.toString()
       .substr( 0, this.toString().indexOf( "(" ) )
       .replace( "function ", "" ); 
}

Dieser Code implementiert auf bequemere Weise eine Antwort, die ich bereits oben in dieser Diskussion gelesen habe. Jetzt habe ich eine Mitgliedsfunktion, die den Namen jedes Funktionsobjekts abruft. Hier ist das vollständige Skript ...

<script language="javascript" TYPE="text/javascript">

    Function.prototype.myname = function() { 
        return this.toString()
            .substr( 0, this.toString().indexOf( "(" ) )
            .replace("function ", "" ); 
    }
    function call_this( _fn ) { document.write( _fn.myname() ); }
    function _yeaaahhh() { /* do something */ }
    call_this( _yeaaahhh ); 

</script>



Einfache Möglichkeit, den Funktionsnamen in der von Ihnen ausgeführten Funktion abzurufen.

function x(){alert(this.name)};x()