在ES6语境下,如何在函数内部拿到函数对象本身?

比如下面代码:

function fn() {
    //有时,我们需要在函数内部访问函数对象本身
    console.log(fn.name);
    console.log(arguments.callee.name);
}
fn();

我们在函数fn中访问fn函数对象本身时,目前有两种方案

  1. 是直接用函数名fn

  2. 是用arguments.callee

在ES6语境下,arguments.callee不能用,用函数名代码不够优雅,不好维护,有没有什么更好的办法呢?

阅读 7k
8 个回答

很值得思考的问题,不过没想到办法,不过给你找一个歪果仁极其 hack 的做法吧,也算是欣赏:

'use strict'

function jamie (){
var callerName;
try { throw new Error(); }
catch (e) { 
    var re = /(\w+)@|at (\w+) \(/g, st = e.stack, m;
    re.exec(st), m = re.exec(st);
    callerName = m[1] || m[2];
}
console.log(callerName);
};

function jiminyCricket (){
   jamie();
}

jiminyCricket(); // jiminyCricket

有时间我会再想一想的。
参考:

命名函数表达式

  var factorial = function f(num){
    if(num<=0){
        return 1;
    }else{
        return num*f(--num);
    }
}

个人觉得主要是看访问函数本身用来做什么。

如果是使用name,那还是直接函数名代码来的实际。

如果是为了某些递归,比如求阶乘的递归,那还是用具名还是比较实际。(具名函数导致name实际上不会和执行函数一样)。

比如下面的阶乘 可以直接使用具名函数来操作,就不会涉及函数对象本身的问题,即使赋值给其他元素

    var factorial2 = (function f(num) {
        return (num == 1 ? num : num * f(num - 1));
    });
    var newFactorial = factorial2;
    console.log(newFactorial(1)); // 1
    console.log(newFactorial(3)); // 6

看看这个:https://github.com/nodejs/nod...
使用了error自带的stack信息,可以搞很多奇怪的事情

代码贴在这里

function CustomError() {
  const oldStackTrace = Error.prepareStackTrace;
  try {
    Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;

    Error.captureStackTrace(this);

    this.stack; // Invoke the getter for `stack`.
  } finally {
    Error.prepareStackTrace = oldStackTrace;
  }
}
function myFunction() {
  const err = new CustomError();

  console.log(err.stack[0]);
  console.log(err.stack[0].getFunctionName);
}
myFunction();

2333以前也在研究这个问题。
企图让函数自动报警自动收集信息,打log
那时候也是想过arguments.callee但是严格模式下报错。
function fn(a){

console.log(/function\s+(\w+)/.exec(a.toString())[1])

}
fn(fn);
这是以前像个做法。
内部给参数,外部给参数。
手动给error 拿stack真是脑洞大

想到一个很low的办法

function fn(name) {
    console.log(name);
}
fn('fn');

函数表达式
var a = function aa(){ aa() }

不就是递归么
楼上var a = function aa(){ aa() }
没毛病

推荐问题
宣传栏