如何从函数内部访问函数名?

// parasitic inheritance
var ns.parent.child = function() {
  var parent = new ns.parent();
  parent.newFunc = function() {

  }
  return parent;
}

var ns.parent = function() {
  // at this point, i want to know who the child is that called the parent
  // ie
}

var obj = new ns.parent.child();

当前回答

你可以使用Function.name:

在大多数JavaScript实现中,一旦你在作用域中有了构造函数的引用,你就可以从它的name属性(例如Function.name,或Object.constructor.name)中获得它的字符串名称

你可以使用Function.callee:

原生论点。调用者方法已弃用,但大多数浏览器支持Function。调用者,它将返回实际调用对象(其代码体): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fcaller

你可以创建一个源映射:

如果你需要的是字面函数签名(它的“名字”)而不是对象本身,你可能不得不求助于一些更定制的东西,比如创建一个你需要经常访问的API字符串值的数组引用。您可以使用Object.keys()和字符串数组将它们映射在一起

其他回答

从正在运行的函数中获取函数名的简单方法。

函数x(){警报(this.name)}; x ()

看这里:http://www.tek-tips.com/viewthread.cfm?qid=1209619

arguments.callee.toString();

似乎正符合你的需要。

动态检索函数名(像魔术变量一样)的一个简单解决方案是使用作用域变量。

{
  function parent() {
    console.log(a.name);
  }; let a = parent
}
{
  function child() {
    console.log(a.name)
  }; let a = child
};

parent();//logs parent
child();//logs child

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

任何构造函数都公开一个属性名,即函数名。你可以通过实例(使用new)或原型访问构造函数:

function Person() {
  console.log(this.constructor.name); //Person
}

var p = new Person();
console.log(p.constructor.name); //Person

console.log(Person.prototype.constructor.name);  //Person

这看起来是我这辈子写过的最愚蠢的东西,但很有趣:D

function getName(d){
  const error = new Error();
  const firefoxMatch = (error.stack.split('\n')[0 + d].match(/^.*(?=@)/) || [])[0];
  const chromeMatch = ((((error.stack.split('at ') || [])[1 + d] || '').match(/(^|\.| <| )(.*[^(<])( \()/) || [])[2] || '').split('.').pop();
  const safariMatch = error.stack.split('\n')[0 + d];

  // firefoxMatch ? console.log('firefoxMatch', firefoxMatch) : void 0;
  // chromeMatch ? console.log('chromeMatch', chromeMatch) : void 0;
  // safariMatch ? console.log('safariMatch', safariMatch) : void 0;
  
  return firefoxMatch || chromeMatch || safariMatch;
}

D -堆栈深度。0 -返回此函数名,1 -父函数,等等; [0 + d] -为了理解,会发生什么; firefoxMatch -适用于safari,但我真的有一点时间测试,因为mac的主人吸烟后回来了,并把我赶走了:'(

测试:

function limbo(){
  for(let i = 0; i < 4; i++){
    console.log(getName(i));
  }
}
function lust(){
  limbo();
}
function gluttony(){
  lust();
}

gluttony();

结果: 铬:

Fitefox:

这个解决方案只是为了好玩而创造的!不要在实际项目中使用它。它不依赖于ES规范,只依赖于浏览器实现。在下次chrome/firefox/safari更新后,它可能会被破坏。 超过这个数就没有错误(ha)处理-如果d将大于堆栈长度-你将得到一个错误; 对于其他浏览器的错误消息模式-你会得到一个错误; 它必须适用于ES6类(.split('.').pop()),但你仍然可以得到一个错误;