为什么名称功能表达式在函数体外不可用

时间:2014-06-01 13:47:07

标签: javascript

命名函数表达式,定义为

var ninja = function myNinja();

有一种无法理解的行为。

看看下面的代码

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

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

这让我感到困惑。

3 个答案:

答案 0 :(得分:2)

  

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

仅在函数声明中。对于命名函数表达式,它具体。它是如何在规范中定义的。

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

  

注意 FunctionExpression 中的标识符可以从 FunctionExpression&#39> 功能体中引用到允许函数递归调用自身。但是,与 FunctionDeclaration 不同, FunctionExpression 中的标识符无法引用,也不会影响包含 FunctionExpression <的范围/ em>的

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

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

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

答案 1 :(得分:2)

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

函数表达式可以选择具有名称。价:

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

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

关于功能名称:

  

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

(强调我的。)

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

答案 2 :(得分:1)

您的函数存储在变量ninja中,因此您无法通过函数名称访问它,只能使用变量名称:

console.log(typeof ninja)

这与下面的函数声明不同,后者可以通过函数名称访问:

function ninja(){

}

还有其他不同之处,例如后者与前者不一样。