是否可以这样做:
myfile.js:
function foo() {
alert(<my-function-name>);
// pops-up "foo"
// or even better: "myfile.js : foo"
}
我的堆栈中有Dojo和jQuery框架,因此,如果它们使它们更容易使用,它们就可以使用。
您应该可以通过使用arguments.callee
来获得它。
尽管您可能必须解析名称,因为它可能包括一些额外的垃圾。不过,在某些实现中,您可以简单地使用arguments.callee.name
来获取名称。
解析:
function DisplayMyName()
{
var myName = arguments.callee.toString();
myName = myName.substr('function '.length);
myName = myName.substr(0, myName.indexOf('('));
alert(myName);
}
foo
的函数,并且您知道它在myfile.js
中,所以为什么需要动态获取此信息?话虽这么说,您可以在函数内部使用arguments.callee.toString()
(这是整个函数的字符串表示形式),然后将函数名的值进行正则表达式。
这里是一个会吐出自己名字的函数:
function foo() {
re = /^function\s+([^(]+)/
alert(re.exec(arguments.callee.toString())[1]);
}
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()将提醒包含函数名称的字符串。JS小提琴演示:http://jsfiddle.net/mjgqfhbe/
并且,如果您不想单击:
function test() {
var z = arguments.callee.name;
console.log(z);
}
>>> (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上。
函数表达式的结果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上。注意:
匿名功能检查没有意义。
- 测试环境
~ $ 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
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.'); }
(function f() {
console.log(f.name); //logs f
})();
打字稿变体:
function f1() {} function f2(f:Function) { console.log(f.name); } f2(f1); //Logs f1
注意仅在符合ES6 / ES2015的引擎中可用。 For more see
如果要使用它作为参数的默认值,则需要考虑对'caller'的第二级调用:
function getFunctionsNameThatCalledThisFunction()
{
return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}
这将动态允许在多个功能中实现可重用的实现。function getFunctionsNameThatCalledThisFunction() { return getFunctionsNameThatCalledThisFunction.caller.caller.name; } function bar(myFunctionName = getFunctionsNameThatCalledThisFunction()) { alert(myFunctionName); } // pops-up "foo" function foo() { bar(); } function crow() { bar(); } foo(); crow();
如果您也想要文件名,这是使用F-3000中另一个问题的答案的解决方案:
function getCurrentFileName() { let currentFilePath = document.scripts[document.scripts.length-1].src let fileName = currentFilePath.split('/').pop() // formatted to the OP's preference return fileName } function bar(fileName = getCurrentFileName(), myFunctionName = getFunctionsNameThatCalledThisFunction()) { alert(fileName + ' : ' + myFunctionName); } // or even better: "myfile.js : foo" function foo() { bar(); }
现在,不是成为一名专业的Web开发人员,他不知道所有存在的所有浏览器的所有历史,这是它在2019年chrome浏览器中对我的工作方式:
function callerName() {
return callerName.caller.name;
}
function foo() {
let myname = callerName();
// do something with it...
}
其他一些答案遇到了一些严格的javascript代码等问题。
alert(arguments.callee.toString());
alert(arguments.callee.name);
对于非匿名函数
function foo()
{
alert(arguments.callee.name)
}
但是如果有错误处理程序,结果将是错误处理程序函数的名称,不是吗?
您所需的一切都很简单。创建函数:
function getFuncName() {
return getFuncName.caller.name
}
之后,只要需要,您只需使用:
function foo() {
console.log(getFuncName())
}
foo()
// Logs: "foo"
根据MDN
警告: ECMAScript(ES5)的第五版禁止在严格模式下使用arguments.callee()。通过给函数表达式命名或在函数必须调用自身的地方使用函数声明来避免使用arguments.callee()。
如上所述,如果您的脚本使用“严格模式”,则适用[[仅。这主要是出于安全原因,遗憾的是目前没有其他选择。
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
alert(fn[1]);
对于呼叫者,只需使用caller.toString()
。
首先,打印
current函数的名称(与其他答案一样)对我来说似乎用途有限,因为您已经知道该函数是什么!
但是,找出calling
函数的名称对于跟踪函数可能非常有用。这是一个正则表达式,但是使用indexOf大约快三倍:function getFunctionName() {
var re = /function (.*?)\(/
var s = getFunctionName.caller.toString();
var m = re.exec( s )
return m[1];
}
function me() {
console.log( getFunctionName() );
}
me();
export function getFunctionCallerName (){
// gets the text between whitespace for second part of stacktrace
return (new Error()).stack.match(/at (\S+)/g)[1].slice(3);
}
然后在您的测试中:
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); }); });
请注意,第三个测试仅在位于/ util / functions中时才有效
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()可选回调,或在超时/间隔回调中(即,您仅传递函数名称)。
getMyName
函数返回调用函数的名称。这是一个hack,依赖于non-standard功能:Error.prototype.stack
。请注意,由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())
关于其他解决方案:arguments.callee
is not allowed in strict mode和Function.prototype.caller
是non-standard and not allowed in strict mode。