How to get the function name from within that function?

前端 未结 20 868
抹茶落季
抹茶落季 2020-11-22 16:06

How can I access a function name from inside that function?

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


        
相关标签:
20条回答
  • 2020-11-22 16:37

    You can't. Functions don't have names according to the standard (though mozilla has such an attribute) - they can only be assigned to variables with names.

    Also your comment:

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

    is inside the function my.namespace.myFunc.getFn

    What you can do is return the constructor of an object created by new

    So you could say

    var obj = new my.namespace.myFunc();
    console.info(obj.constructor); //my.namespace.myFunc
    
    0 讨论(0)
  • 2020-11-22 16:40

    look here: http://www.tek-tips.com/viewthread.cfm?qid=1209619

    arguments.callee.toString();
    

    seems to be right for your needs.

    0 讨论(0)
  • 2020-11-22 16:41

    In ES6, you can just use myFunction.name.

    Note: Beware that some JS minifiers might throw away function names, to compress better; you may need to tweak their settings to avoid that.

    In ES5, the best thing to do is:

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

    Using Function.caller is non-standard. Function.caller and arguments.callee are both forbidden in strict mode.

    Edit: nus's regex based answer below achieves the same thing, but has better performance!

    0 讨论(0)
  • 2020-11-22 16:42

    as part as ECMAScript 6 you can use Function.name method

    function doSomething() {}
    
    alert(doSomething.name); // alerts "doSomething"
    
    0 讨论(0)
  • 2020-11-22 16:43

    ES6 (inspired by sendy halim's answer below):

    myFunction.name
    

    Explanation on MDN. As of 2015 works in nodejs and all major browsers except IE.

    Note: On bound functions this will give "bound <originalName>". You will have to strip the "bound " if you want to get the original name.


    ES5 (inspired by Vlad's answer):

    If you have a reference to the function, you can do:

    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
    }
    
    • I have not run unit tests on this, or verified implementation differences, but in principle it should work, if not leave a comment.
    • Note: won't work on bound functions
    • Note: that caller and callee are considered deprecated.

    [1] I include it here because it is legal and often enough syntax highlighting tools fail to take into account the white space between function name and parenthesis. On the other hand, I'm not aware of any implementation of .toString() that will include white space here, so that's why you can omit it.


    As an answer to the original question, I would drop parasitic inheritance and go for some more traditional OOP design patterns. I wrote a TidBits.OoJs to comfortably write OOP code in JavaScript with a feature set mimicking C++ (not yet complete, but mostly).

    I see from the comments that you would like to avoid passing information parent needs to it's constructor. I must admit that traditional design patterns won't save you from that one though, since it is generally a considered a good thing to make your dependencies obvious and enforced.

    I would also suggest to steer away from anonymous functions. They only make debugging and profiling a PITA because everything just shows up as "anonymous function", and there is no benefit to them that I'm aware of.

    0 讨论(0)
  • 2020-11-22 16:43

    You can use name property to get the function name, unless you're using an anonymous function

    For example:

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

    now let's try with named function

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

    now you can use

    // will return "someMethod"
    p.getSomeMethodName()
    
    0 讨论(0)
提交回复
热议问题