【问题标题】:Why a Name Function Expression not available outside function body [duplicate]为什么名称函数表达式在函数体之外不可用[重复]
【发布时间】:2014-07-21 17:51:51
【问题描述】:

命名函数表达式,定义为

var ninja = function myNinja();

有一种我无法理解的行为。

看看下面的代码

 var ninja = function myNinja() {
   console.log(typeof myNinja) //prints 'function'
 };
 console.log(typeof myNinja) //prints 'undefined'

现在,myNinja 是一个命名函数,据我所知,javascript 允许命名函数超出其自身函数的范围。

这让我很困惑。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    不,函数不是命名函数,它是函数表达式。

    函数表达式可以有一个名字。参考:

    function [name]([param1[, param2[, ..., paramN]]]) {
       statements
    }
    

    来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function

    关于函数名:

    姓名
    函数名称。可以省略,在这种情况下函数 是匿名的。 该名称仅在函数体中是本地的。

    (强调我的。)

    命名函数的语法非常相似,但它是一个声明,而不是一个表达式。

    【讨论】:

    • “不,函数不是命名函数,它是函数表达式。” 是的,它命名函数。具体来说,通过命名函数表达式创建的命名函数。
    • @T.J.Crowder:它特别是一个命名函数表达式。只调用一个命名函数会令人困惑,因为它用于声明的函数,而不是函数表达式。
    • 声明的函数和通过命名函数表达式创建的函数都是命名函数。它有点像“命名函数表达式”的名称。 :-)
    【解决方案2】:

    现在,myNinja 是一个命名函数,据我所知,javascript 允许命名函数超出其自身函数的范围。

    仅在函数声明中。对于命名函数表达式,具体不是的情况。这就是规范中的定义。

    所有血淋淋的细节都是in the spec,最相关的是:

    注意 FunctionExpression 中的 Identifier 可以从 FunctionExpression 的 FunctionBody 内部引用以允许函数递归调用自身。但是,与 FunctionDeclaration 不同,FunctionExpression 中的 Identifier 不能被引用,并且不会影响包含 FunctionExpression。

    因此,如果您将代码更改为:

    function myNinja() {
        console.log(typeof myNinja) //prints 'function'
    }
    var ninja = myNinja;
    console.log(typeof myNinja) //prints 'function' (now we're using a declaration)
    

    ...由于使用函数声明myNinja 被添加到定义它的范围内。 (与所有声明一样,声明也被提升;它不像表达式那样作为分步代码的一部分进行处理。)

    【讨论】:

    • 附带说明:IE8 和更早版本有一个错误,他们将 NFE 处理为 both 声明 and 表达式,所以你会有您期望的范围内的名称,详细信息:blog.niftysnippets.org/2010/09/double-take.html 在 IE9 及更高版本中已修复。
    • 这完全有道理。所以这主要是因为函数表达式与函数声明完全不同。感谢您的快速解释。
    【解决方案3】:

    你的函数被存储在变量ninja中,所以你不能通过函数名访问它,只能通过变量名:

    console.log(typeof ninja)
    

    这与下面的函数声明不同,相反,它可以通过函数名访问:

    function ninja(){
    
    }
    

    还有其他区别,比如后者是“吊装”的,与前者不同。

    【讨论】:

      猜你喜欢
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2015-12-26
      • 2013-02-14
      • 2017-03-12
      • 2012-12-31
      相关资源
      最近更新 更多