Javascript 为什么它被称为函数表达式而不是函数声明?

Javascript 为什么它被称为函数表达式而不是函数声明?,javascript,variables,expression,Javascript,Variables,Expression,我开始学习React,现在我又回到JavaScript中一些更基本的概念上来 我已经了解了函数表达式和函数声明之间的区别,但函数表达式为什么不被称为函数声明仍然让我感到困惑 如果这是一个变量声明: constfoo=5; 那为什么这叫做函数表达式呢 const bar=函数(){ //一些代码 }; 在第二个示例中,不是声明了“const bar”吗?为什么函数表达式和函数声明的命名方式是这样的?为什么函数表达式不称为函数声明,反之亦然 那为什么这叫做函数表达式呢 给变量赋值实际上是一个表达

我开始学习React,现在我又回到JavaScript中一些更基本的概念上来

我已经了解了函数表达式和函数声明之间的区别,但函数表达式为什么不被称为函数声明仍然让我感到困惑

如果这是一个变量声明:

constfoo=5;
那为什么这叫做函数表达式呢

const bar=函数(){
//一些代码
};
在第二个示例中,不是声明了“const bar”吗?为什么函数表达式和函数声明的命名方式是这样的?为什么函数表达式不称为函数声明,反之亦然

那为什么这叫做函数表达式呢

给变量赋值实际上是一个表达式。在您的示例中,这是一个表达式。您还声明了
foo
,但它仍然是一个表达式

类似地,另一个示例
const bar=function(){}
被称为函数表达式,以区分函数声明和函数表达式

函数表达式

const bar = function() {
    // Some code
};
vs函数声明

function foo() {
    // Some code
};

有趣的问题。措辞可能有软边界,这是造成这种混乱的部分原因

首先是一些粗略的定义:

  • 表达:我认为最好用一个例子来思考这个问题
    2*2
    是一个表达式,因为您可以继续对它执行其他操作,如
    2*2-3
    <另一方面,如果(…)不是javascript中的表达式,则它不会解析为一个值,您可以在该值中对其执行进一步的操作。如果(…){…}/2,则执行
    是无效的。这个“定义”有一些漏洞,但对于这个答案来说应该足够好了
  • 声明:声明只是声明要使用某个变量名。因此,在您使用
    const foo=5
    的示例中,实际声明的是
    const foo
    部分,
    =5
    只是初始化声明

记住这一点,让我们考虑两个函数的例子,看看这个术语是如何在这些例子中发挥作用的:

  • const g=function(){}
  • 这里有一个声明,
    const g
    。我们还看到有一个函数被创建并分配给g。我们用
    function(){}
    的结果做了一些事情(我们将它分配给某个对象),这意味着javascript将把它解释为函数表达式

  • 函数f(){}
  • 我们没有将此函数用作表达式(在创建它之后,我们没有对其执行任何其他操作),因此javascript实际上将与第一个示例不同地处理此函数。它将在本地名称空间中声明f,并应用它。如果您只是在
    函数f(){}
    之前添加了一个
    +
    ,那么您将导致javascript将其解释为一个表达式,并且这些功能将被禁用。您可以在开发工具中尝试它-放入
    +函数f(){}
    const g=function f(){}
    ,f将保持未定义状态

    javascript在不同的上下文中对function关键字的处理方式不同,这一事实是这种语言选择的核心。你几乎可以认为“function”关键字有两种不同的含义,所选择的含义取决于上下文。任何时候函数在表达式上下文中使用或未命名时,它都采用“表达式”形式,我们称之为“函数表达式”。否则,它将采用包含一些额外特性的替代形式,比如将函数名声明为局部变量。这可能就是为什么我们将这种替代形式称为函数声明。然而,正如OP正确指出的那样,即使使用
    const f=function(){}
    ,声明仍在发生,而不是通过
    function
    关键字发生


    脚注:对于像
    +函数f(){}
    这样的例子,f不会被定义在与g相同的范围内,但它确实是在f的主体内定义的。换句话说,任何命名函数表达式都在其自身的主体中声明其名称。

    web上有一些相关资源,包括。
    const bar
    初始化是一个函数表达式,因为初始化声明变量的任何东西都是一种或另一种形式的表达式。
    const foo
    是变量声明
    5
    是一个表达式,而不是声明。考虑<代码> const FoO=1+1 < /COD>。显然,
    1+1
    是一个需要与evaluatedRelated相关的表达式:。第一个代码块是StatementList→ 语句列表项→ 宣言→ 词汇退化→ LetOrConst绑定列表→ <代码>常量
    → <代码>常量绑定标识符初始值设定项→ <代码>常量标识符=赋值表达式→ [跳过20个步骤]→ <代码>常量foo=PrimaryExpression→ <代码>常量foo=Literal→ <代码>常量foo=NumericLiteral→ [跳过4个步骤]→ <代码>常量foo=5。第二个块在文本处发散→ 函数表达式→ 等等,看。函数声明来自于声明→ 非常细微的挑剔:一些表达式仍然依赖于上下文;不能任意组合表达式。例如:
    await x
    是一个表达式,但是
    ()=>await x
    无效,因为
    await
    不是直接在
    异步
    函数中使用的。另外,整个
    const foo=5
    是一个声明
    const foo=5
    来自
    const
    Identifier
    =
    AssignmentExpression,它派生自
    cons