[javascript] Wie bekomme ich den Funktionsnamen von dieser Funktion?


7 Answers

ES6 (inspiriert von sendy halim's Antwort unten):

myFunction.name

Erläuterung zu MDN . Ab 2015 funktioniert in Nodejs und allen gängigen Browsern außer IE.

Hinweis: Bei gebundenen Funktionen gibt dies " bound <originalName> ". 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 keine Unit-Tests oder verifizierte Implementierungsunterschiede durchgeführt, aber im Prinzip sollte es funktionieren, wenn nicht einen Kommentar hinterlassen.
  • Hinweis: Funktioniert nicht mit gebundenen Funktionen
  • Hinweis: caller und callee gelten als veraltet.

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

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

Ich sehe aus den Kommentaren, dass Sie vermeiden möchten, dass Informationen über die parent über den Konstruktor ausgegeben werden. Ich muss zugeben, dass traditionelle Designmuster Sie nicht davor bewahren werden, da es allgemein als eine gute Sache angesehen wird, Ihre Abhängigkeiten offensichtlich und erzwungen zu machen.

Ich würde auch vorschlagen, von anonymen Funktionen abzulenken. Sie machen nur das Debugging und Profiling einer PITA, weil alles nur als "anonyme Funktion" angezeigt wird, und es gibt keinen Vorteil für sie, den ich kenne.

Question

Wie kann ich auf einen Funktionsnamen innerhalb dieser Funktion 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();



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")

befindet sich in der Funktion my.namespace.myFunc.getFn

Sie können den Konstruktor eines Objekts, das von new erstellt wurde, zurückgeben

So könnte man sagen

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






Im Rahmen von ECMAScript 6 Sie die Methode Function.name verwenden

function doSomething() {}

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



Jeder constructor legt einen Eigenschaftsnamen name , der den Funktionsnamen darstellt. Sie greifen auf den constructor über eine Instanz (unter Verwendung von new ) oder einen prototype :

function Person() {
  console.log(this.constructor.name); //Person
}

var p = new Person();
console.log(p.constructor.name); //Person

console.log(Person.prototype.constructor.name);  //Person



Das hat für mich funktioniert.

function AbstractDomainClass() {
    this.className = function() {
        if (!this.$className) {
            var className = this.constructor.toString();
            className = className.substr('function '.length);
            className = className.substr(0, className.indexOf('('));
            this.$className = className;
        }
        return this.$className;
    }
}

Testcode:

var obj = new AbstractDomainClass();
expect(obj.className()).toBe('AbstractDomainClass');



Sie können Error.stack verwenden, um den Namen der Funktion und die genaue Position Ihres Standorts zu verfolgen.

Siehe stacktrace.js




Sie könnten Function.name :

In den meisten Implementierungen von JavaScript können Sie, sobald Sie den Verweis Ihres Konstruktors im Gültigkeitsbereich haben, den String-Namen von seiner name-Eigenschaft abrufen (z. B. Function.name oder Object.constructor.name)

Sie könnten Function.callee :

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

Sie könnten eine Quellkarte erstellen :

Wenn Sie die Literalfunktionssignatur (den "Namen") benötigen und nicht das Objekt selbst, müssen Sie möglicherweise auf etwas mehr angepasstes zugreifen, wie zum Beispiel das Erstellen eines Array-Verweises der API-String-Werte, die Sie benötigen häufig zugreifen. Sie können sie zusammen mit Object.keys() und Ihrem String-Array Object.keys() oder in Mozillas Source Maps-Bibliothek auf GitHub nachsehen, für größere Projekte: https://github.com/mozilla/source-map






Related