在严格模式下复制 arguments.callee

Posted

技术标签:

【中文标题】在严格模式下复制 arguments.callee【英文标题】:Replicating arguments.callee in strict mode 【发布时间】:2012-04-18 01:49:46 【问题描述】:

我第一次在严格模式下工作,而且,你知道吗,这也是多年来第一次能够使用非严格模式属性会很有用。我的question here 概述了我遇到的确切问题,但如果我仍然可以访问arguments.callee,我制定的解决方案可以适应更具可扩展性的东西。

在不命名函数的情况下,有什么方法可以在严格模式下获得对我当前范围内的函数的引用?

【问题讨论】:

您可以将您的函数分配给某个变量。 进步是一件美好的事情。 @wheresrhys - 仅供参考,避免该名称的方法几年前停止工作,我已经更新了我的答案,以防你依赖它。 :-) 【参考方案1】:

在不命名函数的情况下,有什么方法可以在严格模式下获得对我当前范围内的函数的引用?

在 2012 年 this answer was originally written 时,您在链接解决方案中使用的命名函数表达式存在实现错误。现在还没有,距离有这些错误的浏览器仍然大量流通已经 。因此,在(非常)后 IE8 世界中,您的命名函数表达式方法很好:

UsageGraph = Graph.extend(
   generateScale: function GS() 
       var parentMethod = this.constructor._super.generateScale;
       if(parentMethod === GS) 
           parentMethod = this.constructor._super.constructor._super.generateScale;
       
       parentMethod.call(this); // run the parent's method
       //do additional stuff
   
);

但问题是你是否可以避免拥有名字。在 2012 年,如果您真的不希望函数有名称,我的解决方案是将匿名函数分配给变量:

UsageGraph = Graph.extend(function()
   var GS = function() 
       var parentMethod = this.constructor._super.generateScale;
       if(parentMethod === GS) 
           parentMethod = this.constructor._super.constructor._super.generateScale;
       
       parentMethod.call(this); // run the parent's method
       //do additional stuff
   ;

   return generateScale: GS;
());

但这不再起作用了;从 ES2015 开始,即使该函数也有一个名称,从分配给它的变量的名称推断:

var GS = function()  ;
console.log(GS.name); // "GS"

如果你真的不希望它有名字,可以避免它,但你必须努力打破规范定义的自动命名,例如通过该函数是另一个函数的返回值:

var GS = (() => function()  )();
console.log(GS.name); // ""

因此,如果避免使用名称很重要,您可以这样做:

UsageGraph = Graph.extend(function()
   const generateScale = (() => function() 
       let parentMethod = this.constructor._super.generateScale;
       if(parentMethod === generateScale) 
           parentMethod = this.constructor._super.constructor._super.generateScale;
       
       parentMethod.call(this); // run the parent's method
       //do additional stuff
   )();

   return generateScale;
());

【讨论】:

+1 提醒您 callee,这似乎是合理的,但失去对函数对象的动态引用仍然很遗憾。 @wheresrhys:(它是 generateScale: function GS() 在 Safari 2 上失败 @Knu - 恕我直言,我非常怀疑如果按上述方式使用,那是真的,该语法与 javascript 本身一样古老。不过就算是真的,也没关系。 :-) Safari 2 的最后一个版本于 2006 年发布,12 年前。这与当今世界无关。 :-) @amn - 绝对。正如我在回答中所说,“我不喜欢它,但我们在那里。:-)”【参考方案2】:

是的,但不是...我不确定这是否与您所说的“命名”方式相同:

var foo = function bob() 
    // call bob();


// bob is undeclared; here it's foo!

http://jsfiddle.net/4y8pY/

【讨论】:

小心使用 IE8 及更早版本,当您使用命名函数表达式时,它会创建 two completely separate function objects 并泄漏 bob 符号。 还要注意提问者说没有命名函数”(我的重点)。

以上是关于在严格模式下复制 arguments.callee的主要内容,如果未能解决你的问题,请参考以下文章

js_递归函数在严格模式下的调用方法

JavaScript函数用法

使用箭头函数的几个注意事项

ECMAScrip5 二

在严格模式下获取当前函数名

es5严格模式