【问题标题】:What's the point of naming function expressions if you can't really reference them by the names you give them? [duplicate]如果你不能通过你给它们的名字来真正引用它们,那么命名函数表达式有什么意义呢? [复制]
【发布时间】:2016-03-13 21:30:38
【问题描述】:

如果你不能通过你给它们的名字来真正引用它们,那么命名函数表达式有什么意义呢?

var f = function g() {
    console.log("test");
};

g(); // ReferenceError: g is not defined

【问题讨论】:

  • 那个函数不是像f()那样可以调用吗?
  • 我知道我在这里有点挑剔,但如果它被命名,它就不是一个匿名函数。他们是对立的。
  • 我从未在我的帖子中说过一个函数可以同时是匿名的和命名的。
  • @trex005 如果您既想提供帮助又想挑剔,您可以说给出的示例称为function expression:P

标签: javascript


【解决方案1】:

哦,但是您可以通过该名称引用它们。这些名称只存在于函数范围内

var f = function g() {
    // In here, you can use `g` (or `f`) to reference the function
    return typeof g;
};

console.log( typeof g );
// It only exists as `f` here
console.log( f() );

文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function#Named_function_expression

【讨论】:

  • 请注意,其中一个原因是使用f 来引用此处的函数是危险的——例如f 可以在函数表达式之后重新定义为 null,然后尝试在函数内调用 f() 会抛出异常。
【解决方案2】:

我发现特别有用的一个优点是它在调试时很有帮助。

发生错误时,您会在控制台的堆栈跟踪中看到函数名称。否则堆栈跟踪中的行将仅引用匿名函数。

您还可以通过给函数命名来使函数的用途更清晰。

【讨论】:

  • 您能否详细说明一下,以免这更像是评论?
  • 完成。但是,我认为在这方面没有更多需要详细说明。无论如何,我认为它应该是答案的一部分。
  • 在这个特定的例子中,当函数被分配给一个变量时,如果你省略了g,函数名称将被推断为f。但我知道它在其他情况下会很有用。
  • 你说得对,我并没有真正关注这个例子。
【解决方案3】:

如果您创建一个传递的递归函数,这一点很重要。当您命名一个函数时,它就会在自己的范围内了解自己。

在这里,我创建了一种创建递归函数的工厂函数。为了使递归函数正常工作,他们需要了解自己。

您可以将其想象为更广泛的应用,例如将递归函数作为模块导出返回。

var 
func = (function () {
  return function rec (a) {
    console.log(a);
    return a >= 5 ? 'done' : rec(a + 1);
  };
}),
invoke = function (f, args) {
  return f.apply(null, args);
};

console.log(
  invoke(func(), [1])
);

【讨论】:

    【解决方案4】:

    根据定义,您定义的不是匿名函数:

    function [name]([param[, param[, ... param]]]) {
       statements
    }
    

    姓名:

    函数名。可以省略,在这种情况下函数 被称为匿名函数。

    另外,很多人会考虑

    var f = function() {
         return 'test';
     };
    

    不要成为匿名函数,因为您现在可以通过 var 名称 f() 调用它,并且现在可以将该函数作为参数传递给名称为 functionThatTakesCallback(f) 的其他函数。

    在我的脑海中,真正的匿名函数没有任何名称,例如传递给回调的东西:

    $('#id').on('click', function(){
      console.log("I am anonymous");
    });
    

    或作为函数立即运行:

    (function(when){
      console.log("run me :", when);
    })("right now");
    

    使用您现在使用的语法,在 ES6(大多数非 IE 浏览器实现此功能)中,f.nameg。这在调试时很有用

    【讨论】:

      【解决方案5】:

      你可以用它来重复:

      var f = function g (n, m) {
          if (n>0) {
              return g(n - 1, m = m + 'meta');
          }
          return m + 'test';
      };
      
      console.log(f(10, 'super'));
      

      【讨论】:

        猜你喜欢
        • 2011-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-27
        • 2011-05-10
        • 2011-03-23
        • 2010-11-08
        相关资源
        最近更新 更多