有多少JavaScript程序在浏览器中的单个网页被执行?

问题描述 投票:67回答:4

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解析器遇到SCRIPT元素时间结束时,则执行该元素的内部程序(再一次执行程序,解析器移动到后面的SCRIPT元素)的HTML代码。

再说,这样做的工作:

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

在这里,我的理解是,全局对象(其作为在全球执行上下文的变量对象)存在(并保持)在所有时间,所以第一个JavaScript程序将创建函数对象,并为它的引用,那么第二JavaScript程序将使用该引用调用的函数。因此,所有的JavaScript程序(一个网页内)“用”同一个全局对象,并通过一个JavaScript程序进行全局对象的所有变化可以通过后续运行的所有JavaScript程序进行观察。

现在,注意,这...

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

在上述情况下,报警电话将不执行,因为“富()”语句抛出一个的ReferenceError(它打破了整个JavaScript程序),因此,所有后续语句不执行。

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

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

现在,警报调用不会得到执行。第一个JavaScript程序抛出一个的ReferenceError(并因此中断),但第二个JavaScript程序正常运行。当然,浏览器会报告错误(虽然它执行后续的JavaScript程序,错误发生后)。

现在,我的结论是:

  • 该网页的HTML代码中的每个SCRIPT元素代表一个单独的JavaScript程序。这些程序的HTML解析器遇到他们立即执行。
  • 同一网页中的所有JavaScript程序“用”同一全局对象。全球对象存在于所有时间(从网页被取出,直到网页被破坏的时刻)。 JavaScript程序可以操纵全局对象,并且由一个JavaScript程序做全局对象的所有变化可以在随后的所有JavaScript程序进行观察。
  • 如果一个JavaScript程序中断(通过其引发的错误),这并不妨碍后续的JavaScript程序执行。

请其实检查这篇文章,并告诉我,如果我得到了什么。

此外,我还没有发现,说明在这个帖子中提到的行为的资源,我认为浏览器厂商必须有地方发表过这样的资源,因此,如果您想要了解这些,请提供链接到他们。

javascript browser hoisting
4个回答
15
投票

梅德Soshnikov已经回答了你的问题。每<script>元件被作为程序执行时,由ECMAScript规范所定义的。有一个单一页面内每个程序使用一个全局对象。这是真正的。


19
投票

功能提升 - 该功能的其余部分之前评估function语句的过程 - 是ECMAScript标准IIRC的部分(我不能找到一个参考的权利,但我记得提到它EMCAScript的看到讨论)。 script标签的评价是HTML标准的一部分。它没有指定,他们是“独立的程序”,在这么多的话,但它说,该脚本元素在它们在文档中出现的顺序进行评估。这就是为什么在后来的脚本标记功能都没有悬挂:脚本尚未评估。这也解释了为什么一个脚本停止不切断后续的脚本:在当前的脚本停止评估,接下来的一个开始。


7
投票

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


4
投票

想想这另一种方式是伪当地VS全局范围。每个脚本声明具有局部范围,这是目前的方法/功能,以及访问当前(先前声明)全球范围。每当一个方法/函数在SCRIPT块中定义,它然后被添加到全球范围内,并通过它后脚本块变为可访问。

另外,这里是从W3C上脚本报关/处理/修改更多参考:

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

  1. 作为文档被加载在订单中的所有脚本元素进行评价。
  2. 一个脚本元素中的所有脚本结构生成SGML CDATA进行评估。他们的组合生成的文本被插入到文档中代替SCRIPT元素。
  3. 所产生的被CDATA重新评估。

This是脚本/功能评价/声明另一个很好的资源。

© www.soinside.com 2019 - 2024. All rights reserved.