如何从该函数中获取函数名称?
如何从函数内部访问函数名称?
// 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();
在ES5中,最好的做法是:
function functionName(fun) { var ret = fun.toString(); ret = ret.substr('function '.length); ret = ret.substr(0, ret.indexOf('(')); return ret; }
使用Function.caller
是非标准的,在严格模式下禁止使用arguments.callee
。
编辑:nus的基于正则expression式的答案达到相同的事情,但有更好的performance!
在ES6中,你可以使用myFunction.name
。
注意:小心一些JS缩小器可能会丢弃函数名称,以便更好地压缩; 你可能需要调整他们的设置,以避免这种情况。
ES6 (灵感来自下面的sendy halim的回答):
myFunction.name
关于MDN的解释 截至2015年在nodejs和除IE以外的所有主stream浏览器。
注意:在绑定函数上,这会给“ bound <originalName>
”。 如果你想得到原来的名字,你将不得不去掉“绑定”。
ES5 (由弗拉德的答案启发):
如果你有一个函数的引用,你可以这样做:
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 }
- 我没有对此进行unit testing,或validation实现的差异,但原则上它应该工作,如果不发表评论。
- 注意:在绑定函数上不起作用
- 注意:这个
caller
和callee
被认为是不赞成的。
[1] 我把它包含在这里是因为它是合法的,经常有足够的语法高亮工具没有考虑函数名和括号之间的空白。 另一方面,我不知道.toString()的任何实现,这将包括在这里的空白,所以这就是为什么你可以省略它。
作为对原始问题的回答,我会放弃寄生inheritance,寻找更传统的OOPdevise模式。 我写了一个TidBits.OoJs ,用JavaScript模拟C ++(尚未完成,但大部分)的function, 以便于编写OOP代码。
我从意见中看到,您希望避免将parent
需要传递给构造函数。 我必须承认,传统的devise模式并不能让你从这个模式中解脱出来,因为让你的依赖变得明显和强制通常被认为是一件好事。
我也build议摆脱匿名function。 他们只对PITA进行debugging和分析,因为所有的东西都显示为“匿名函数”,对他们我没有任何好处。
你正在做的是将一个未命名的函数赋值给一个variables。 您可能需要命名函数expression式( http://kangax.github.com/nfe/ )。
var x = function x() { console.log( arguments.callee.name ); } x();
不过我不确定这是多less浏览器; IE6有一个问题,使得你的函数的名字泄漏到外部的范围。 另外,arguments.callee是一种不赞成,如果你使用strict mode
将导致错误。
这可能适合你:
function foo() { bar(); } function bar() { console.log(bar.caller.name); }
运行foo()会输出“foo”,或者如果您从匿名函数调用,则会输出undefined。
它也与构造函数一起工作,在这种情况下,它将输出调用构造函数的名称(例如“Foo”)。
更多信息在这里: https : //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Caller
他们声称这是非标准的,但也支持所有主stream浏览器:Firefox,Safari,Chrome,Opera和IE。
任何constructor
公开一个属性name
,这是函数名称。 你通过一个实例(使用new
)或一个prototype
来访问constructor
:
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
你不能。 函数根据标准没有名字(尽pipemozilla有这样一个属性) – 它们只能被赋值给带有名字的variables。
还有你的评论:
// access fully qualified name (ie "my.namespace.myFunc")
在函数my.namespace.myFunc.getFn中
你可以做的是返回由new创build的对象的构造函数
所以你可以说
var obj = new my.namespace.myFunc(); console.info(obj.constructor); //my.namespace.myFunc
您可以使用name
属性来获取函数名称,除非您使用匿名函数
例如:
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());
现在让我们尝试使用命名函数
var Person = function Person () { this.someMethod = function someMethod() {}; };
现在你可以使用
// will return "someMethod" p.getSomeMethodName()
你可以使用Function.name
:
在JavaScript的大多数实现中,一旦你在构造函数的作用域中引用了,你可以从它的name属性中得到它的string名(例如Function.name或者Object.constructor.name
你可以使用Function.callee
:
本机arguments.caller
方法已被弃用,但大多数浏览器都支持Function.caller
,它将返回实际的调用对象(它的代码体): https : //developer.mozilla.org/en-US/docs/Web/的JavaScript /参考/ Global_Objects /function/来电?redirectlocale = EN-US&redirectslug = JavaScript的%2FReference%2FGlobal_Objects%2FFunction%2Fcaller
你可以创build一个源地图 :
如果你需要的是字面函数签名(“名称”)而不是对象本身,你可能不得不采取一些更加自定义的方式,比如创build一个你需要的APIstring值的数组引用经常访问。 您可以使用Object.keys()
和您的string数组将它们映射到一起,或者查看GitHub上的Mozilla的源映射库,以获得更大的项目: https : //github.com/mozilla/source-map
你可以使用这个,但不是所有的浏览器,只有那些支持Error.stack的
function VamosRafa(){ var a = new Error().stack.match(/at (.*?) /); console.log(a[1]); } VamosRafa();
当然这是为了目前的function,但你明白了。
干杯!
作为ECMAScript 6
一部分,您可以使用Function.name方法
function doSomething() {} alert(doSomething.name); // alerts "doSomething"
看这里: http : //www.tek-tips.com/viewthread.cfm?qid=1209619
arguments.callee.toString();
似乎是正确的为您的需求。
我知道这是一个古老的问题,但最近我一直在试图装饰一些React组件的方法,出于debugging的目的,一直面临着一些类似的问题。 正如人们已经说过的, arguments.caller
和arguments.callee
在严格模式下是被禁止的,在你的React转发中,默认情况下这可能是启用的。 你可以禁用它,或者我已经能够想出另一个黑客,因为在React中,所有的类函数都被命名,你可以这样做:
Component.prototype.componentWillMount = function componentWillMount() { console.log('Callee name: ', this.__proto__.constructor.toString().substr(0,30)); ... }
这对我有效。
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; } }
testing代码:
var obj = new AbstractDomainClass(); expect(obj.className()).toBe('AbstractDomainClass');
我有一个类似的问题,我解决它如下:
Function.prototype.myname = function() { return this.toString() .substr( 0, this.toString().indexOf( "(" ) ) .replace( "function ", "" ); }
这个代码以更舒适的方式实现了我在这里讨论的顶部已经阅读的一个回应。 现在我有一个成员函数检索任何函数对象的名称。 这是完整的脚本…
<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>
您可以使用Error.stack来追踪函数名称和确切位置。
请参阅stacktrace.js
从正在运行的function中获取function名称的简单方法。
function x(){alert(this.name)};x()