有可能这样做吗:

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

我的堆栈中有Dojo和jQuery框架,所以如果它们中的任何一个使工作更容易,都可以使用它们。


既然你写了一个名为foo的函数,你知道它在myfile.js中,为什么你需要动态地获取这个信息?

也就是说,你可以在函数内部使用arguments.callee.toString()(这是整个函数的字符串表示),并regex出函数名的值。

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

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

Try:

alert(arguments.callee.toString());

在ES5及以上版本中,无法访问该信息。

在旧版本的JS中,你可以使用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);
}

获取当前函数名。


对于非匿名函数

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

但在错误处理程序的情况下结果应该是错误处理程序函数的名称,不是吗?


这应该做到:

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

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


这必须归入“世界上最丑陋的黑客”的范畴,但你看。

首先,打印当前函数的名称(就像在其他答案中一样)对我来说用处有限,因为您已经知道这个函数是什么!

然而,找出调用函数的名称对于跟踪函数可能非常有用。这是一个regexp,但使用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();

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

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

这里的优点是dispatcher可以很容易地重用,并且不需要接收dispatcher队列作为参数,相反,它与调用名称一起隐含…

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


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


这是我在这里看到的一些回应的组合。(在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/


这个问题的最新答案可以在这个答案中找到: https://stackoverflow.com/a/2161470/632495

如果你不想点击:

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

根据MDN

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

如上所述,这只适用于你的脚本使用“严格模式”。这主要是出于安全考虑,遗憾的是目前还没有替代方案。


下面代码段中的getMyName函数返回调用函数的名称。这是一个黑客,依赖于非标准的特性:Error.prototype.stack。注意,由Error.prototype.stack返回的字符串格式在不同的引擎中实现是不同的,所以这可能不会在任何地方都适用:

函数getMyName() { var e = new错误('dummy'); Var stack = e.stack .split(“\ n”)[2] // " at functionName(…)"“= >”functionName .replace (/ ^ \ s + \ s + (+ ?) \ s。+/g, '$1'); 返回栈 } 函数foo () { 返回getMyName () } 功能栏(){ 返回foo () } console.log (bar ())

关于其他解决方案:争论。严格模式下不允许使用callee,严格模式下不允许使用Function.prototype.calleris非标准的。


这里有一句话:

    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测试。


函数表达式的结果

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

这里有一个可行的方法:

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中时,第三个测试才会工作


你所需要的很简单。 创建函数:

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

在此之后,无论何时你需要,你只需使用:

function foo() { 
  console.log(getFuncName())
}

foo() 
// Logs: "foo"

(function f() {
    console.log(f.name);  //logs f
})();

打印稿变化:

function f1() {} 
function f2(f:Function) {
   console.log(f.name);
}

f2(f1);  //Logs f1

注意仅适用于ES6/ES2015兼容引擎。更多信息请参见


这是伊戈尔·奥斯特鲁莫夫回答的一个变体:

如果你想使用它作为参数的默认值,你需要考虑对'caller'的二级调用:

function getFunctionsNameThatCalledThisFunction()
{
  return getFunctionsNameThatCalledThisFunction.caller.caller.name;
}

这将动态地允许多个函数中的可重用实现。

getFunctionsNameThatCalledThisFunction()函数 { 返回getFunctionsNameThatCalledThisFunction.caller.caller.name; } (myFunctionName = getFunctionsNameThatCalledThisFunction()) { 警报(myFunctionName); } //弹出"foo" 函数foo () { 酒吧(); } 乌鸦()函数 { 酒吧(); } foo (); 乌鸦();

如果你也想要文件名,这里是使用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();
}

由于arguments.callee.name是非标准的,并且在ECMAScript 5严格模式(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)中被禁止,动态检索函数名的一个简单解决方案[像魔术变量一样]是使用作用域变量和function .name属性。

{
  function foo() {
    alert (a.name);
  }; let a = foo
}
{
  function foo2() {
    alert(a.name)
  }; let a = foo2
};
foo();//logs foo
foo2();//logs foo2

注意:嵌套函数不再是源元素,因此不会被提升。而且,这种技术不能用于匿名函数。


arguments对象是一个局部变量,可在所有非箭头函数中使用。 可以使用函数的arguments对象来引用函数内部的参数。 它对调用函数的每个参数都有条目,第一个条目的索引为0。

所以你基本上可以使用arguments。callee。name但是在命名函数内部,像这样:

function i_have_a_name() {
    console.log(`My name is:`, arguments.callee.name)
}
> i_have_a_name()
My name is: i_have_a_name

不幸的是,它不能在箭头函数中使用:

const i_have_a_name = () => {
    console.log(`My name is:`, arguments.callee.name)
}
> i_have_a_name()
Uncaught ReferenceError: arguments is not defined
    at i_have_a_name (REPL3:2:32)

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments