gpt4 book ai didi

javascript - 为什么 JavaScript 不需要 main() 函数?

转载 作者:IT王子 更新时间:2023-10-29 03:22:06 24 4
gpt4 key购买 nike

许多编程语言需要一个特殊的用户编写的函数来标记开始
的执行。例如,在 C 中,此函数必须始终具有名称 main() .在
但是,JavaScript 不需要这样的功能。

JavaScript 中缺少这种专用的顶级函数的逻辑原因是什么?我知道这是某种理论问题,但我无法在网上找到答案。

最佳答案

因为整个代码块实际上是一大块 main .在 JavaScript 中,全局代码可以具有函数代码可以具有的所有构造,并且可以逐步执行,就像函数一样。事实上,当 JS 引擎将代码块作为一个整体处理时,它所做的事情与处理函数调用时所做的事情非常相似。请参阅规范的部分 10.4.1 (“输入全局代码”)和 10.4.3 (“输入功能代码”)并注意它们的相似程度。

C 不允许全局级别的逐步代码(您可以拥有各种初始化程序,它们可以逐步进行,但这是一个不同的主题)。所以 C 需要一个明确的入口点( main )。在 JavaScript 中,入口点是代码的开头。

关于您在下面关于全局代码是否是顺序的问题。答案是肯定的,它就像函数中的代码那样。所以:

var x, y, z;
x = 1;
y = 2;
z = x + y;
alert("z is " + z);

...会提醒 "z is 3" .代码按顺序运行,从上到下。

但是,在执行逐步代码之前会发生一些事情,这很有用。最重要的是,输入范围的源文本中的任何声明都在逐步代码开始之前处理。 JavaScript 有两种主要类型的声明:变量声明和函数声明:
  • var 声明的任何变量的名称在执行任何逐步代码之前,将被添加到作用域(值为 undefined)。 (更多:Poor, misunderstood var )
  • 在执行任何逐步代码之前,处理函数声明并将函数名称添加到作用域中。 (JavaScript 还有其他东西,称为函数表达式,它是逐步代码。更多内容见下文。)

  • 例如,在这个源文本中:
    var x;
    x = 1;
    foo();

    function foo() {
    }

    声明是
    var x;
    function foo() {
    }

    和逐步代码是
    x = 1;
    foo();

    首先处理声明。这就是拨打 foo 的原因作品。 (这些相同的规则适用于函数内的源文本。)这种在其他任何事情之前的声明处理有时被称为“提升”,因为在某种意义上,声明是从它们在源文本中的位置提升并移到最开始的。我更愿意将其视为两次通过源代码:第一次执行声明,第二次执行逐步代码。

    (旁注:在同一个范围内多次声明一个变量是完全合法的 [尽管毫无意义]。声明两个同名的函数也是合法的;后一个声明覆盖了前一个。)

    (旁注 2:ES2015 [ES6] 引入了 letconst 变量声明,它们的行为与 var 有所不同。你不能用它们声明一个变量两次,它们有块作用域,你不能在声明它的语句之前使用变量。所以它们通常不会被提升 [有点类似于提升,因为它们甚至在 let x 或任何行之前阻止访问包含范围中的阴影变量]。)

    更多细节,可能会有点技术性:
    var
    var在逐步代码运行之前发生,你可能想知道这个:
    var x = 1;

    这是在逐步代码之前发生还是作为它的一部分发生?答案是,实际上,这只是两种截然不同的事物的简写:
    var x;
    x = 1;
    var x;部分发生在逐步代码之前, x = 1; part 是逐步代码,当我们在序列中到达它时执行。所以:
    alert(x); // "undefined" -- there **is** a variable `x`; it has the value `undefined`
    var x = 1;
    alert(x); // "1" -- now `x` has the value `1`

    函数声明

    JavaScript 有两个不同但非常相似的东西:函数声明和函数表达式。您可以通过是否将结果函数用作定义它的表达式的一部分来判断哪个是哪个。

    这是一个函数声明:
    function foo() {
    }

    这些都是函数表达式(我们使用结果函数值作为表达式的一部分;在计算机科学术语中,函数用作右手值):
    // 1: Assigning the result to something
    var x = function() {
    };

    // 2: Passing the result into a function
    bar(function() {
    });

    // 3: Calling the function immediately
    (function(){
    })();

    // 4: Also calling the function immediately (parens at end are different)
    (function(){
    }());

    // 5: Also calling the function immediately
    !function(){
    }();

    // 6: Syntax error, the parser needs *something* (parens, an operator like ! or
    // + or -, whatever) to know that the `function` keyword is starting an *expression*,
    // because otherwise it starts a *declaration* and the parens at the end don't make
    // any sense (and function declarations are required to have names).
    function(){
    }();

    规则是在逐步代码开始之前处理函数声明。函数表达式与所有其他表达式一样,在遇到它们的地方进行处理。

    最后一个旁注:这是一个 命名 函数表达式:
    var f = function foo() {
    };

    我们将它用作右手边的值,所以我们知道它是一个表达式;但它有一个像函数声明那样的名字。这是完全有效且合法的 JavaScript,它的目的是创建一个具有适当名称 ( foo ) 的函数作为逐步代码的一部分。函数的名称不会添加到作用域中(就像它是函数声明一样)。

    但是,您不会在很多地方看到命名函数表达式,因为 JScript(Microsoft 的 JavaScript 引擎)获取它们 horribly and utterly wrong ,在两个不同的时间创建两个独立的函数。

    关于javascript - 为什么 JavaScript 不需要 main() 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9015836/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com