【问题标题】:Make sure a Javascript script is first to run?确保首先运行 Javascript 脚本?
【发布时间】:2012-03-12 07:58:48
【问题描述】:

我注意到某些脚本在某个页面上似乎先于其他脚本被调用,我想知道,脚本加载的具体顺序是什么?引用 .js 脚本之前的页面内?它们是按从第一个提到的<script> 到最后一个页面的顺序运行的,还是依赖于浏览器?如何确保特定脚本首先在页面中运行?

【问题讨论】:

    标签: javascript hoisting operator-precedence


    【解决方案1】:

    只要没有脚本被动态加载或标记为异步或延迟,脚本就会按照页面中遇到的顺序运行或评估。因此,遇到的第一个脚本首先运行。

    必须加载的外部引用脚本文件将导致所有进一步的 javascript 执行等待,直到加载、解析并运行该外部引用文件。

    因此,正常(非异步、非延迟)javascript 的评估顺序是 100% 确定的,因为它在页面中遇到的顺序。

    【讨论】:

    • 请提供来自 ECMA-262 版本 5+ 的引用,声明这是根据标准指定的行为。您确定它在所有浏览器和平台上都能以这种方式工作,而不仅仅是侥幸吗?
    • @ingyhere - 我不知道哪里有参考,我现在没时间看。这就是 javascript 的工作方式——如果您有理由对此提出质疑,请说明原因。 Javascript从上/下执行。它绝对必须在浏览器之间保持一致,否则很多页面会中断,因为人们一直依赖于从上到下执行的 javascript。几乎任何语言都必须在代码的不同部分之间提供有保证的执行顺序,因为这通常是使您的逻辑正常工作所必需的。
    • 我知道从一个浏览器到另一个浏览器的浏览器行为差异的唯一地方是当脚本通过 javascript 动态插入时,这个答案特别排除了,我不相信这个问题正在询问。
    • 我不同意答案的一件事是措辞“运行顺序”,因为我更喜欢“评估顺序”,因为某些代码指定了稍后调用的函数或其他实体。加载顺序(至少)在 W3Cs HTML 4.01 规范,第 18.2.4 节动态修改文档中指定。 JavaScript 词典的执行顺序在 ECMA-262 5.1 版/2011 年 6 月中指定。
    【解决方案2】:

    默认情况下,script 标签在 HTML 文档中遇到时会按顺序下载和评估。

    但是,如果您使用 asyncdefer 属性,则在脚本完成下载(异步)或页面完成加载(延迟)之后执行。

    【讨论】:

    • 不要指望 defer 属性在解析之后才停止执行(否则它将是加载和就绪事件的一个很好的替代方案)。在 HTML 4 中,defer 只是提示脚本没有创建内容,因此浏览器可以在执行时继续加载。在 HTML5 中,defer 表示“等待解析完成”。 HTML5 没有得到足够好的支持,无法依赖指定的行为,也许几年后还没有。
    【解决方案3】:

    脚本按照它们在 html 文件中的评估顺序运行,就像您从上到下阅读它一样。

    但是,对于已实现这些功能的浏览器,异步和延迟可以覆盖这一点。

    【讨论】:

      【解决方案4】:

      我注意到某些脚本似乎在某些脚本之前被调用 页。我想知道,脚本加载的具体顺序是什么?

      这是由 W3C 在其语言规范中设置的。以HTML 4.01 Specification 为例,它在Section 18.2.4 Dynamic modification of documents, item 1 中定义。

      在引用 .js 脚本之前的页内?

      见上文。不,内联脚本和链接脚本的处理方式相同。

      它们是否按页面中从第一个提到到最后一个的顺序运行, 还是这取决于浏览器?

      规范要求它们从上到下按顺序运行。您必须找到一个根据规范实现该语言的浏览器。我现在想不出任何以不同方式处理 SCRIPT 标签的方法,但我确信这是可能的。

      要考虑的另一件事是“运行”的定义。这听起来像是语义解析,但事实并非如此。与任何编程语言一样,JavaScript 本身就是按照标准设计的。 JavaScript 在ECMA-262 5.1 Edition / June 2011 standard 中指定,在第 7 节词汇约定中从左到右进行计算。 (行尾被视为下一行的最左侧字符。)本文档还提供了语句和其他操作的评估顺序的约定,例如 WHILE 或 FOR 语句。

      如何确保特定脚本首先在页面中运行?

      (1) 将其放在顶部,(2) 选择实现语言规范的浏览器。

      但是,我觉得这个问题背后可能还有更多的东西。如果您试图阻止意外代码的执行,则必须阻止它,直到 ONLOAD 事件处理程序注册该页面已完成。 (只需将您的操作包含在一个函数中或用 IF 将它们包围以检查布尔标志,即 ONLOAD 将 isLoaded 设置为 true。)然后,当 ONLOAD 事件处理程序触发时,您可以按自己的计划启动操作,而无需不必担心诸如未实例化的 DOM 对象之类的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-16
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        相关资源
        最近更新 更多