javascript länge - Wie bekomme ich den Funktionsnamen von dieser Funktion?




9 Answers

In ES5 ist das Beste, was zu tun ist:

function functionName(fun) {
  var ret = fun.toString();
  ret = ret.substr('function '.length);
  ret = ret.substr(0, ret.indexOf('('));
  return ret;
}

Die Verwendung von Function.caller ist nicht Standard. Function.caller und arguments.callee sind beide im strikten Modus verboten.

Edit: Nus Regex-basierte Antwort unten erreicht das gleiche, hat aber eine bessere Leistung!

In ES6 können Sie einfach myFunction.name .

Hinweis: Achten Sie darauf, dass einige JS-Minifier Funktionsnamen wegwerfen, um besser komprimieren zu können. Sie müssen möglicherweise ihre Einstellungen optimieren, um dies zu vermeiden.

title tag

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



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 .




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.




Sie können die name -Eigenschaft verwenden, um den Funktionsnamen abzurufen, sofern Sie keine anonyme Funktion verwenden

Beispielsweise:

var Person = function Person () {
  this.someMethod = function () {};
};

Person.prototype.getSomeMethodName = function () {
  return this.someMethod.name;
};

var p = new Person();
// will return "", because someMethod is assigned with anonymous function
console.log(p.getSomeMethodName());

Jetzt versuchen wir es mit der benannten Funktion

var Person = function Person () {
  this.someMethod = function someMethod() {};
};

Jetzt können Sie verwenden

// will return "someMethod"
p.getSomeMethodName()



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!




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));
...
}



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 Memberfunktion, die den Namen eines 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>



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

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




Related

javascript function