我可以在JavaScript中获取当前正在运行的函数的名称吗?

有没有可能这样做:

myfile.js: function foo() { alert(<my-function-name>); // pops-up "foo" // or even better: "myfile.js : foo" } 

我已经在我的堆栈中有了Dojo和jQuery框架,所以如果其中任何一个更容易,它们都可用。

你应该可以通过使用arguments.callee来得到它。

你可能不得不parsing这个名字,因为它可能会包含一些额外的垃圾。 不过,在一些实现中,您可以使用arguments.callee.name来获取名称。

parsing:

 function DisplayMyName() { var myName = arguments.callee.toString(); myName = myName.substr('function '.length); myName = myName.substr(0, myName.indexOf('(')); alert(myName); } 

来源: Javascript – 获取当前的函数名称 。

对于非匿名函数

 function foo() { alert(arguments.callee.name) } 

但是如果是error handling程序,结果将是error handling程序函数的名称,不是吗?

这应该做到这一点:

 var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/); alert(fn[1]); 

对于调用者,只需使用caller.toString()

这必须在“世界上最丑陋的黑客”的类别,但在这里你走。

首先,打印当前函数的名称(如在其他答案中)似乎对我有限,因为您已经知道函数是什么了!

但是,找出调用函数的名称可能对跟踪function非常有用。 这是一个正则expression式,但使用indexOf将快大约3倍:

 function getFunctionName() { var re = /function (.*?)\(/ var s = getFunctionName.caller.toString(); var m = re.exec( s ) return m[1]; } function me() { console.log( getFunctionName() ); } me(); 

根据MDN

警告:第5版ECMAScript(ES5)禁止在严格模式下使用arguments.callee()。 避免使用arguments.callee(),通过给函数expression式一个名字或者在函数必须调用自己的地方使用一个函数声明。

如上所述, 只有当您的脚本使用“严格模式” 时才适用。 这主要是出于安全原因,可悲的是目前没有其他的select。

另一个用例可以是在运行时绑定的事件分派器:

 MyClass = function () { this.events = {}; // Fire up an event (most probably from inside an instance method) this.OnFirstRun(); // Fire up other event (most probably from inside an instance method) this.OnLastRun(); } MyClass.prototype.dispatchEvents = function () { var EventStack=this.events[GetFunctionName()], i=EventStack.length-1; do EventStack[i](); while (i--); } MyClass.prototype.setEvent = function (event, callback) { this.events[event] = []; this.events[event].push(callback); this["On"+event] = this.dispatchEvents; } MyObject = new MyClass(); MyObject.setEvent ("FirstRun", somecallback); MyObject.setEvent ("FirstRun", someothercallback); MyObject.setEvent ("LastRun", yetanothercallback); 

这里的优点是调度程序可以很容易地重用,不必接收调度队列作为参数,而是隐含了调用名称…

最后,这里给出的一般情况将是“使用函数名称作为参数,所以你不必显式地传递它”,这在很多情况下可能是有用的,比如jquery animate()可选的callback函数,或超时/间隔callback(即只传递一个函数NAME)。

这是一个可行的方法:

 export function getFunctionCallerName (){ // gets the text between whitespace for second part of stacktrace return (new Error()).stack.match(/at (\S+)/g)[1].slice(3); } 

然后在你的testing中:

 import { expect } from 'chai'; import { getFunctionCallerName } from '../../../lib/util/functions'; describe('Testing caller name', () => { it('should return the name of the function', () => { function getThisName(){ return getFunctionCallerName(); } const functionName = getThisName(); expect(functionName).to.equal('getThisName'); }); it('should work with an anonymous function', () => { const anonymousFn = function (){ return getFunctionCallerName(); }; const functionName = anonymousFn(); expect(functionName).to.equal('anonymousFn'); }); it('should work with an anonymous function', () => { const fnName = (function (){ return getFunctionCallerName(); })(); expect(/\/util\/functions\.js/.test(fnName)).to.eql(true); }); }); 

请注意,如果testing位于/ util / functions中,则只有第三个testing才有效

既然你已经写了一个名为foo的函数,你知道它在myfile.js为什么你需要dynamic获取这些信息呢?

也就是说,你可以在函数内部使用arguments.callee.toString() (这是整个函数的string表示forms),并将函数名的值正则expression出来。

这是一个会吐出自己名字的函数:

 function foo() { re = /^function\s+([^(]+)/ alert(re.exec(arguments.callee.toString())[1]); } 

更新的答案可以在这个答案find: https : //stackoverflow.com/a/2161470/632495

如果你不喜欢点击:

 function test() { var z = arguments.callee.name; console.log(z); } 

下面代码片段中的getMyName函数返callback用函数的名称。 这是一个黑客,并依赖于非标准的function: Error.prototype.stack

 function getMyName() { var e = new Error('dummy'); var stack = e.stack .split('\n')[2] // " at functionName ( ..." => "functionName" .replace(/^\s+at\s+(.+?)\s.+/g, '$1' ); return stack } function foo(){ return getMyName() } function bar() { return foo() } console.log(bar()) 

我在这里看到的几个答复的组合。 (在FF,Chrome,IE11testing)

 function functionName() { var myName = functionName.caller.toString(); myName = myName.substr('function '.length); myName = myName.substr(0, myName.indexOf('(')); return myName; } function randomFunction(){ var proof = "This proves that I found the name '" + functionName() + "'"; alert(proof); } 

调用randomFunction()会提示包含函数名称的string。

JS小提琴演示: http : //jsfiddle.net/mjgqfhbe/

这里是一个class轮:

  arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', '') 

喜欢这个:

  function logChanges() { let whoami = arguments.callee.toString().split('\n')[0].substr('function '.length).replace(/\(.*/, "").replace('\r', ''); console.log(whoami + ': just getting started.'); } 

信息在2016年是实际的。


函数声明的结果

结果在歌剧院

 >>> (function func11 (){ ... console.log( ... 'Function name:', ... arguments.callee.toString().match(/function\s+([_\w]+)/)[1]) ... })(); ... ... (function func12 (){ ... console.log('Function name:', arguments.callee.name) ... })(); Function name:, func11 Function name:, func12 

结果在Chrome中

 (function func11 (){ console.log( 'Function name:', arguments.callee.toString().match(/function\s+([_\w]+)/)[1]) })(); (function func12 (){ console.log('Function name:', arguments.callee.name) })(); Function name: func11 Function name: func12 

结果在NodeJS中

 > (function func11 (){ ... console.log( ..... 'Function name:', ..... arguments.callee.toString().match(/function\s+([_\w]+)/)[1]) ... })(); Function name: func11 undefined > (function func12 (){ ... console.log('Function name:', arguments.callee.name) ... })(); Function name: func12 

在Firefox中不起作用。 在IE和Edge上未经testing。


函数expression式的结果

结果在NodeJS中

 > var func11 = function(){ ... console.log('Function name:', arguments.callee.name) ... }; func11(); Function name: func11 

结果在Chrome中

 var func11 = function(){ console.log('Function name:', arguments.callee.name) }; func11(); Function name: func11 

在Firefox,Opera中不起作用。 在IE和Edge上未经testing。

笔记:

  1. 匿名函数没有意义检查。
  2. testing环境

 ~ $ google-chrome --version Google Chrome 53.0.2785.116 ~ $ opera --version Opera 12.16 Build 1860 for Linux x86_64. ~ $ firefox --version Mozilla Firefox 49.0 ~ $ node node nodejs ~ $ nodejs --version v6.8.1 ~ $ uname -a Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux 

尝试:

 alert(arguments.callee.toString()); 

答案很简短: alert(arguments.callee.name);