javascript - länge - title tag wordpress




Wie bekomme ich den Funktionsnamen von dieser Funktion? (12)

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');

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();

Dies könnte für Sie funktionieren:

function foo() { bar(); }

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

Running foo () wird "foo" oder undefined ausgeben, wenn Sie von einer anonymen Funktion aufrufen.

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

Weitere Informationen finden Sie hier: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller

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


Einfacher Weg, den Funktionsnamen von der Funktion zu erhalten, die Sie gerade ausführen.

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


Es sieht aus wie das blödeste Ding, das ich in meinem Leben geschrieben habe, aber es ist lustig: D

function getName(d){
  const error = new Error();
  const firefoxMatch = (error.stack.split('\n')[0 + d].match(/^.*([email protected])/) || [])[0];
  const chromeMatch = ((((error.stack.split('at ') || [])[1 + d] || '').match(/(^|\.| <| )(.*[^(<])( \()/) || [])[2] || '').split('.').pop();
  const safariMatch = error.stack.split('\n')[0 + d];

  // firefoxMatch ? console.log('firefoxMatch', firefoxMatch) : void 0;
  // chromeMatch ? console.log('chromeMatch', chromeMatch) : void 0;
  // safariMatch ? console.log('safariMatch', safariMatch) : void 0;

  return firefoxMatch || chromeMatch || safariMatch;
}

d - Stapeltiefe. 0 - gebe diesen Funktionsnamen, 1 - Eltern usw. zurück;
[0 + d] - nur um zu verstehen - was passiert;
firefoxMatch - funktioniert für Safari, aber ich hatte wirklich ein wenig Zeit zum Testen, weil Mac's Besitzer nach dem Rauchen zurückgekommen ist und mich vertrieben hat: '(

Testen:

function limbo(){
  for(let i = 0; i < 4; i++){
    console.log(getName(i));
  }
}
function lust(){
  limbo();
}
function gluttony(){
  lust();
}

gluttony();

Ergebnis:
Chrom:

Fitefox:

Diese Lösung wurde nur zum Spaß erstellt ! Benutze es nicht für echte Projekte. Es hängt nicht von der ES-Spezifikation ab, es hängt nur von der Browser-Realisierung ab. Nach dem nächsten Chrome / Firefox / Safari Update kann es kaputt gehen.
Mehr als das gibt es keine Fehler (ha) Verarbeitung - wenn d mehr als Stack-Länge sein wird - Sie werden einen Fehler erhalten;
Für andere wowsers Fehler message Muster - Sie erhalten einen Fehler;
Es muss für ES6-Klassen .split('.').pop() ( .split('.').pop() ), aber Sie können einen Fehler bekommen;


Ich weiß, dass dies eine alte Frage ist, aber in letzter Zeit hatte ich ein ähnliches Problem, als ich versuchte, die Methoden einiger React Components zu Debugging-Zwecken zu dekorieren. Wie bereits erwähnt, sind arguments.caller und arguments.callee im strikten Modus verboten, der wahrscheinlich standardmäßig in React tranpiling aktiviert ist. Sie können es entweder deaktivieren, oder ich konnte einen weiteren Hack erstellen, da in React alle Klassenfunktionen benannt sind, können Sie Folgendes tun:

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

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

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 dies verwenden, aber es ist nicht für alle Browser, nur diejenigen, die Error.stack unterstützen

function VamosRafa(){ 
  var a = new Error().stack.match(/at (.*?) /);
  console.log(a[1]);
} 
VamosRafa();

Natürlich ist dies für die aktuelle Funktion, aber Sie bekommen die Idee.

Prost!


Was Sie tun, ist unbenannte Funktion zu einer Variablen zuzuweisen. Wahrscheinlich brauchen Sie stattdessen einen benannten Funktionsausdruck ( http://kangax.github.com/nfe/ ).

var x = function x() {
    console.log( arguments.callee.name );
}
x();

aber ich bin mir nicht sicher, wie viel Cross-Browser das ist; Es gibt ein Problem mit IE6, das das Namensleck der Funktion in den äußeren Bereich bringt. arguments.callee ist ebenfalls veraltet und führt zu einem Fehler, wenn Sie den strict mode .


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.


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





function