2012-05-16 41 views
28

我想要做的Get JavaScript function-object from its name as a string?从Javascript函数参考中获取名称作为字符串?

这是相反的,因为:

function foo() 
{} 

function bar(callback) 
{ 
    var name = ???; // how to get "foo" from callback? 
} 

bar(foo); 

我如何获得一个参考后面的函数的名称?

+0

'变种的蝙蝠= foo的;酒吧(蝙蝠)' - 现在应该打印什么? – Alnitak

+1

@Alnitak。它应该打印'foo'。这是函数名称。 'bat'是一个引用'foo'函数的变量。 – gdoron

+0

如果回调没有名字会发生什么? - 即'bar(function(){...});' – Spudley

回答

24

如果您不能使用myFunction.name那么您可以:

// Add a new method available on all function values 
Function.prototype.getName = function(){ 
    // Find zero or more non-paren chars after the function start 
    return /function ([^(]*)/.exec(this+"")[1]; 
}; 

或为现代浏览器,唐不支持name属性(do它们存在)直接添加:

if (Function.prototype.name === undefined){ 
    // Add a custom property to all function values 
    // that actually invokes a method to get the value 
    Object.defineProperty(Function.prototype,'name',{ 
    get:function(){ 
     return /function ([^(]*)/.exec(this+"")[1]; 
    } 
    }); 
} 
+0

呵呵,现在我明白了,'('如果是'exec'匹配,不是正则表达式的一部分。cool。+1 。顺便说一句,为什么它不提醒'foo)'? – gdoron

+0

为什么它不匹配'foo){...'? – gdoron

+1

@gdoron由于正则表达式必须按顺序匹配字符,直到它停止。正则表达式中的'函数'开始匹配,然后消耗零或更多的任何东西 - 但 - 一个(字符(尽可能多))。一旦完成了,它必须停止;它不能“跳过”不匹配并继续。 – Phrogz

13
var name = callback.name; 

MDN

名称属性返回一个函数的名称,或匿名函数一个空字符串:

只是注意,该酒店是不规范

Live DEMO

+1

'[名称]属性不是标准的'不再是真实的,它在ECMA 6.0/2015中:http://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname /另请参见http: //www.2ality.com/2015/09/function-names-es6.html – CoDEmanX

1
var x = function fooBar(){}; 
console.log(x.name); 
// "fooBar" 
0

尝试访问.name属性:

callback.name 
4
function bar(callback){ 
    var name=callback.toString(); 
    var reg=/function ([^\(]*)/; 
    return reg.exec(name)[1]; 
} 

>>> function foo() { }; 
>>> bar(foo); 
"foo" 
>>> bar(function(){}); 
"" 
+0

比我更优雅的正则表达式;不错:)你确定所有的浏览器都会在领先的'function'之后放置一个空格吗? – Phrogz

+0

@Progrog我有足够的信心不要改变上述。如果存在边缘情况,它只会影响匿名函数,并且可以轻松调整“bar”以将其考虑在内。 – kojiro

+0

看过你的代码,我回想起很久以前规范化的字符串表示和IIRC需要的空间规格。 – Phrogz

0

如果您正在寻找在一个特定的对象事件的功能,这可能会帮助:

var a = document.form1 
a.onsubmit.name 
2

可以提取对象和函数的名称用:

function getFunctionName() 
{ 
    return (new Error()).stack.split('\n')[2].split(' ')[5]; 
} 

例如:

function MyObject() 
{ 
} 

MyObject.prototype.hi = function hi() 
{ 
    console.log(getFunctionName()); 
}; 

var myObject = new MyObject(); 
myObject.hi(); // outputs "MyObject.hi" 
+0

这可能会起作用,但构建堆栈跟踪比解析this.toString()不是更昂贵? – Gili

+0

是的,但我只是用它来调试消息。上述答案只会返回“嗨”,这将返回“MyObject.hi”。 –

+1

这对于调试非常好。感谢或分享! – Raisch

0

对我来说,只是一个小修改(添加父前\),这项工作:

if (Function.prototype.name === undefined){ 
    // Add a custom property to all function values 
    // that actually invokes a method to get the value 
    Object.defineProperty(Function.prototype,'name',{ 
    get:function(){ 
     return /function ([^\(]*)/.exec(this+"")[1]; 
    } 
    }); 
}