代码之家  ›  专栏  ›  技术社区  ›  Å ime Vidas Zim84

浏览器中的一个网页执行多少个JavaScript程序?

  •  66
  • Å ime Vidas Zim84  · 技术社区  · 14 年前

    JavaScript程序由语句和函数声明组成。执行JavaScript程序时,会发生以下两个步骤:

    1. 扫描代码中的函数声明和每个func。声明被“执行”(通过创建函数对象)并创建对该函数的命名引用(以便可以从语句中调用该函数)

    2. 语句按顺序执行(求值)(正如它们出现在代码中一样)

    正因为如此,这个 :

    <script>
        foo();
        function foo() {
            return;
        }
    </script>
    

    虽然“foo”函数是在声明之前调用的,但它是有效的,因为函数声明是在语句之前求值的。

    不起作用 :

    <script>
        foo();
    </script>
    <script>
        function foo() {
            return;
        }
    </script>
    

    将抛出ReferenceError(“未定义foo”)。 这就得出了这样的结论:网页的HTML代码中的每个脚本元素都代表一个单独的JavaScript程序,每当HTML解析器遇到一个脚本元素时,它就会执行该元素中的程序(然后一旦执行了该程序,解析器就会移到该脚本元素后面的HTML代码)。

    :

    <script>
        function foo() {
            return;
        }
    </script>
    <script>
        foo();
    </script>
    

    我在这里的理解是,全局对象(在全局执行上下文中充当变量对象)一直存在(并保留),因此第一个JavaScript程序将创建function对象并对其进行引用,然后第二个JavaScript程序将使用该引用调用函数。因此,所有JavaScript程序(在一个网页中)“使用”同一个全局对象,并且一个JavaScript程序对全局对象所做的所有更改都可以被随后运行的所有JavaScript程序观察到。

    注意这个。。。

    <script>
        // assuming that foo is not defined
        foo();
        alert(1);
    </script>
    

    在上述情况下,警报调用 ,因为“foo()”语句抛出一个ReferenceError(它会中断整个JavaScript程序),因此所有后续语句都不会执行。

    然而,在这种情况下。。。

    <script>
        // assuming that foo is not defined
        foo();
    </script>
    <script>
        alert(1);
    </script>
    

    现在,警报呼叫 会被处决吗

    现在,我的结论是:

    • 同一网页中的所有JavaScript程序“使用”相同的全局对象。全局对象始终存在(从抓取网页到销毁网页)。JavaScript程序可以操作全局对象,并且一个JavaScript程序对全局对象所做的所有更改都可以在所有后续的JavaScript程序中观察到。
    • 如果一个JavaScript程序中断(抛出错误),这不会阻止后续JavaScript程序执行。

    请查查这篇文章,如果我有什么问题请告诉我。

    另外,我还没有找到解释本文中提到的行为的资源,我假设浏览器制造商一定在某处发布了此类资源,因此如果您知道这些资源,请提供指向它们的链接。

    4 回复  |  直到 6 年前
        1
  •  15
  •   Tim Down    14 年前

    德米特里·索什尼科夫回答了你的问题。每 <script> 元素作为程序执行,如ECMAScript规范所定义。单个页面中的每个程序都使用一个全局对象。就这样。

        2
  •  19
  •   Chuck    14 年前

    功能提升评估的过程 function 函数其余部分之前的语句是ECMAScript标准IIRC的一部分(我现在找不到引用,但我记得看到EMCAScript的讨论提到了它)。评价 script

        3
  •  7
  •   Mike Stay    14 年前

    它们是独立的程序,但它们修改共享的全局对象。

        4
  •  4
  •   bryan.taylor    14 年前

    另一种考虑这一点的方法是伪局部vs全局范围。每个脚本声明对其当前方法/函数都有一个本地作用域,以及对当前(以前声明的)全局作用域的访问。每当在脚本块中定义一个方法/函数时,它就会被添加到全局作用域中,并由之后的脚本块访问。

    另外,这里还有一个来自 W3C 关于脚本声明/处理/修改:

    文档的动态修改 可建模如下:

    1. 加载文档时,将按顺序计算所有脚本元素。
    2. 给定脚本元素中生成 对sgmlcdata进行评估。他们的 组合生成的文本插入到 代替脚本的文档
    3. 重新计算生成的CDATA。

    This 是另一个关于脚本/函数求值/声明的好资源。