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

Why a Name Function Expression not available outside function body

本文关键字:函数体 函数 表达式 为什么      更新时间:2023-09-26

定义为

的命名函数表达式
var ninja = function myNinja();

有一种我无法理解的行为

看一下下面的代码

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

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

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

函数表达式可以有一个可选的名称。裁判:

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

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

关于函数名:

<

名称/strong>
函数名。可以省略,在哪种情况下函数是匿名的。

(我强调。)

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

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

只能在函数声明中使用。对于命名函数表达式来说,它是而不是。这就是规范中的定义。

所有的血色细节都在规格书中,最相关的是:

FunctionExpression中的标识符可以从FunctionExpression的 FunctionBody内部引用,以允许函数递归地调用自己。然而,与FunctionDeclaration不同的是,FunctionExpression中的标识符不能被引用,也不会影响包含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被添加到定义它的作用域中。(与所有声明一样,声明也是提升的;它不像表达式那样作为分步代码的一部分来处理。)

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

console.log(typeof ninja)

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

function ninja(){
}

还有其他不同之处,如后者与前者不同,后者是"提升的"。