我可以在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。
笔记:
- 匿名函数没有意义检查。
- 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);