当启用use strict时,如何在JavaScript中找到调用函数?

Jam*_*ber 41 javascript use-strict

use strict启用时是否可以看到函数的被调用者/调用者?

'use strict';

function jamie (){
    console.info(arguments.callee.caller.name);
    //this will output the below error
    //uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
};

function jiminyCricket (){
   jamie();
}

jiminyCricket ();
Run Code Online (Sandbox Code Playgroud)

p.s*_*w.g 42

对于它的价值,我同意上述评论.对于您要解决的任何问题,通常都有更好的解决方案.

但是,仅出于说明的目的,这是一个(非常丑陋)的解决方案:

'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
Run Code Online (Sandbox Code Playgroud)

我只在Chrome,Firefox和IE11中对此进行了测试,因此您的里程可能会有所不同.

  • 这很好用.我们不得不使用throw版本而不是@ inetphantom的解决方案,因为我们必须使用的嵌入式JavaScript引擎没有填充Error().stack直到它被抛出. (2认同)

ine*_*tom 27

请注意,这不应用于生产目的.这是一个丑陋的解决方案,它可以帮助调试,但如果您需要来自调用者的东西,请将其作为参数传递或将其保存到可访问的变量中.

@pswg答案的简短版本(没有抛出错误,只是实例化一个):

    let re = /([^(]+)@|at ([^(]+) \(/g;
    let aRegexResult = re.exec(new Error().stack);
    sCallerName = aRegexResult[1] || aRegexResult[2];
Run Code Online (Sandbox Code Playgroud)

完整片段:

'use strict'

function jamie (){
    var sCallerName;
    {
        let re = /([^(]+)@|at ([^(]+) \(/g;
        let aRegexResult = re.exec(new Error().stack);
        sCallerName = aRegexResult[1] || aRegexResult[2];
    }
    console.log(sCallerName);
};

function jiminyCricket(){
   jamie();
};

jiminyCricket(); // jiminyCricket
Run Code Online (Sandbox Code Playgroud)

  • 您添加了生产使用的警告...嗯...该功能确实不纯粹。但这应该是不在生产代码中使用它的一个严重原因吗?该代码似乎相当稳定(据我判断)。一个非常有趣的应用是日志记录方法。在这种情况下,在参数中传递调用者姓名将是乏味、臃肿且容易出错的。因此,在我看来,为什么以及何时应在生产中使用某些代码的决定主要取决于软件设计和一些常识。如果它对我有用,我会*很高兴*在生产代码中使用它。 (2认同)

小智 6

它对我不起作用这是我最终做的事情,以防万一它可以帮到某人

function callerName() {
  try {
    throw new Error();
  }
  catch (e) {
    try {
      return e.stack.split('at ')[3].split(' ')[0];
    } catch (e) {
      return '';
    }
  }

}
function currentFunction(){
  let whoCallMe = callerName();
  console.log(whoCallMe);
}
Run Code Online (Sandbox Code Playgroud)


Lar*_*rry 5

您可以使用以下方法获取堆栈跟踪:

console.trace()
Run Code Online (Sandbox Code Playgroud)

但这可能对您没有必要,例如需要与呼叫者联系。

参见https://developer.mozilla.org/en-US/docs/Web/API/Console/trace