我能否获得JavaScript中当前正在运行的函数的名称?

问题描述 投票:171回答:19

是否可以这样做:

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

我的堆栈中有Dojo和jQuery框架,因此,如果它们使它们更容易使用,它们就可以使用。

javascript jquery dojo
19个回答
184
投票

您应该可以通过使用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);
}

来源:Javascript - get current function name


1
投票
由于您已经编写了一个名为foo的函数,并且您知道它在myfile.js中,所以为什么需要动态获取此信息?

话虽这么说,您可以在函数内部使用arguments.callee.toString()(这是整个函数的字符串表示形式),然后将函数名的值进行正则表达式。

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

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


1
投票
我在这里看到的一些回答的组合。 (已在FF,Chrome,IE11中测试)

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/


1
投票
有关此问题的最新答案,可以在以下答案中找到:https://stackoverflow.com/a/2161470/632495

并且,如果您不想单击:

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


1
投票
信息是2016年的真实信息。


函数声明的结果

Opera中的结果

>>> (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上。

注意:

    匿名功能检查没有意义。
  1. 测试环境

  • ~ $ 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

  • 0
    投票
    这里是一个班轮:

    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.'); }


    0
    投票
    (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

    0
    投票
    [这是Igor Ostroumov's的变体:

    如果要使用它作为参数的默认值,则需要考虑对'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(); }


    0
    投票
    自从问了这个问题以来,当前功能的名称以及如何获得它似乎在过去十年中已经发生了变化。

    现在,不是成为一名专业的Web开发人员,他不知道所有存在的所有浏览器的所有历史,这是它在2019年chrome浏览器中对我的工作方式:

    function callerName() { return callerName.caller.name; } function foo() { let myname = callerName(); // do something with it... }

    其他一些答案遇到了一些严格的javascript代码等问题。 

    -2
    投票
    尝试:

    alert(arguments.callee.toString());


    -7
    投票
    答案很短:alert(arguments.callee.name);

    67
    投票

    对于非匿名函数

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

    但是如果有错误处理程序,结果将是错误处理程序函数的名称,不是吗?


    37
    投票

    您所需的一切都很简单。创建函数:

    function getFuncName() {
       return getFuncName.caller.name
    }
    

    之后,只要需要,您只需使用:

    function foo() { 
      console.log(getFuncName())
    }
    
    foo() 
    // Logs: "foo"
    

    28
    投票

    根据MDN

    警告: ECMAScript(ES5)的第五版禁止在严格模式下使用arguments.callee()。通过给函数表达式命名或在函数必须调用自身的地方使用函数声明来避免使用arguments.callee()。​​

    如上所述,如果您的脚本使用“严格模式”,则适用[[仅。这主要是出于安全原因,遗憾的是目前没有其他选择。


    21
    投票
    这应该做:

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

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

    10
    投票
    这必须归入“世界上最丑陋的骇客”类别,但您可以从这里开始。

    首先,打印

    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();

    8
    投票
    这是一种可行的方法:

    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中时才有效

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

    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()可选回调,或在超时/间隔回调中(即,您仅传递函数名称)。


    3
    投票
    下面的代码段中的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 modeFunction.prototype.callernon-standard and not allowed in strict mode
    © www.soinside.com 2019 - 2024. All rights reserved.