从实例化函数中获取函数名称

时间:2016-03-01 04:40:13

标签: javascript

如何在不知道其名称的情况下从其中获取实例化 JavaScript函数的名称?

我需要它的原因是因为我开始使用异常,我想稍后将异常的名称作为字符串获取,而不是手动将名称写入异常函数本身,就像在MDN文档中的示例中所示: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html

示例:

function MyException(message) {
    this.message = message;
    this.name = 'MyException';  // How to get function name automatically?
    this.toString = function() {
        return this.name + ': ' + this.message;
    };
}

try {
    throw new MyException('Hello world');
}
catch (e) {
    alert(e);  // "MyException: Hello world"
}

Function.name,但只要函数被实例化(通过new运算符)就不可用,因为函数会成为没有任何属性或方法的对象。

2 个答案:

答案 0 :(得分:1)

函数为arguments对象提供了callee属性,这是一个指向调用函数的指针(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/argumentshttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)。所以arguments.callee是同一个实例化函数(现在是对象)的原始函数。

ECMAScript 2015引入了Function.name属性(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name),该属性受Chrome,Opera,Firefox和Safari支持,但不支持Internet Explorer(在我的IE11中为undefined),所以通过arguments.callee.name访问实例化函数的名称适用于除IE之外的所有浏览器。

但是,通过为Function.prototype属性创建一个辅助方法(因此它继承到所有函数)然后在所有浏览器中从实例化函数(然后是对象)内部获取名称有一个小技巧从已有的toString()方法中提取函数名称:

Function.prototype.getName = function()
{
    var funcName = this.toString().substr(9);
    return funcName.substr(0, funcName.indexOf('(')).trim();
};

function MyException(message) {
    this.message = message;
    this.name = arguments.callee.getName();  // Get orig. function name
    this.toString = function() {
        return this.name + ': ' + this.message;
    };
}

try {
    throw new MyException('Hello world');
}
catch (e) {
    alert(e);  // "MyException: Hello world"
}

注1:不支持匿名功能,因为它们没有名称。但是可以使用命名函数:

var MyException = function MyException(message) {
    // ...
}

注2:arguments.callee在ES5严格模式下不可用。

注3:我使用trim的{​​{1}}方法,该方法在IE9 +中可用。如果不可用,请创建一个垫片:

String.prototype.trim()

答案 1 :(得分:0)

访问Function.name属性,注意支持的浏览器列表,如果它适合您,那就太棒了)

function MyException(message) {
    this.message = message;
    this.name = MyException.name;  // 'MyException'
    this.toString = function() {
        return this.name + ': ' + this.message;
    };
}