第 2 章 HTML中的JavaScript
脚本在HTML中的装载方式决定下载、解析、执行与DOMContentLoaded的相对顺序,也决定故障是否阻塞页面。
直觉:先画执行与所有权
脚本在HTML中的装载方式决定下载、解析、执行与DOMContentLoaded的相对顺序,也决定故障是否阻塞页面。 真正的难点不是让一次示例得到预期输出,而是让绑定、对象、任务、权限和资源在异常、取消、重复与版本切换后仍可解释。先预测:若只保存最终截图,最可能隐藏哪一种陈旧状态?
权威目录定位
本页依据 Wiley 第4版官方31页目录样章与中文版公开完整目录锁定范围。目录名称用于一对一追踪,正文为独立教学重构;新浏览器差异、安全与可观察性补充会明确披露:
- 2.1
<script>元素 - 2.1.1 标签占位符
- 2.1.2 推迟执行脚本
- 2.1.3 异步执行脚本
- 2.1.4 动态加载脚本
- 2.1.5 XHTML中的变化
- 2.1.6 废弃的语法
- 2.2 行内代码与外部文件
- 2.3 文档模式
- 2.4
<noscript>元素 - 2.5 小结
本页逐项覆盖 11 个公开目录条目,并纳入正常、边界、失败和恢复验收。
核心概念与所有权
、、、、。 每个概念都要回答:谁创建输入,状态保存在哪里,哪个任务或版本可修改它,结束后由谁清理。
| # | 概念 | 工程含义 |
|---|---|---|
| 1 | script元素 | 在HTML中声明脚本资源、脚本类型和装载执行策略的元素。 |
| 2 | defer | 让外部经典脚本并行下载并在文档解析完成后按文档顺序执行的属性。 |
| 3 | async | 让独立外部脚本下载完成后尽快执行且不保证彼此顺序的属性。 |
| 4 | 动态脚本 | 由运行中代码创建并插入文档、其装载时序需显式管理的脚本元素。 |
| 5 | 文档模式 | 影响浏览器布局和部分脚本兼容行为的HTML解析兼容模式。 |
机制拆解
1. 经典脚本的默认阻塞
解析器遇到无属性的外部经典脚本时通常暂停文档解析,等待下载与执行。把脚本放在错误位置会延迟首屏;但简单地全部改成async又会破坏依赖顺序。
先预测:若省略这一层,哪个绑定、任务、权限或资源会先偏离?
2. defer与async按依赖选择
defer适合依赖DOM和相互有顺序的页面脚本,async适合彼此独立的统计或广告脚本。模块脚本具有不同默认行为,迁移时要同时验证依赖图、执行时刻和错误传播。
先预测:若省略这一层,哪个绑定、任务、权限或资源会先偏离?
3. 动态加载需要Promise化
插入script元素只启动请求,不代表资源可用。加载器应对load、error、超时、重复URL和取消定义单一结果,并缓存同一资源的进行中Promise,避免并发调用重复执行。
先预测:若省略这一层,哪个绑定、任务、权限或资源会先偏离?
六阶段证据链
可操作链条是:解析HTML → 发现脚本资源 → 并行或阻塞下载 → 按策略执行 → 触发文档事件 → 验证失败回退。正常样本证明能力,边界样本证明预算,失败样本证明拒绝,恢复样本证明任务、状态和资源重新收敛。
最小可运行实验
以下代码用于独立观察本页机制;生产实现还需加入输入验证、兼容策略、权限、取消与清理。
const script = document.createElement("script");
script.src = "/feature.js";
const loaded = new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = reject;
});
document.head.append(script);
await loaded;证据记录把目录、运行时与状态摘要放在一起:
book: JavaScript高级程序设计(第4版)
page: jpg-02-javascript-in-html
official_entries: 11
sample: normal | boundary | failure | recovery
browser_version: fixed
input_fixture: fixed
first_divergence: null
cleanup_complete: true故障脚本一次只改变一个变量:
baseline -> inject(exception | cancel | duplicate | denied | stale-cache)
observe -> stop_at_first_divergence
recover -> replay_same_runtime_and_input
assert -> one_state_owner && stable_output && no_stale_task && no_resource_leak常见误区与故障注入
验收矩阵
| 样本 | 输入与环境变化 | 预期状态 | 通过条件 |
|---|---|---|---|
| 正常 | 合法输入、权限、顺序与版本 | 六阶段完成 | 输出和状态摘要一致 |
| 边界 | 空值、极限容量、重复事件或慢任务 | 达到预算不越界 | 主线程与内存有界 |
| 失败 | 异常、取消、拒权、断网或旧产物 | 首偏离点停止 | 明确传播、回滚或降级 |
| 恢复 | 修复后重放同一输入 | 收敛到正常轨迹 | 无陈旧任务、监听器和资源泄漏 |
本页签发不变量是:脚本依赖顺序可证明;页面解析不被无意阻塞;加载失败能显式传播且不会重复执行。 单次成功、平均耗时或最终截图不能替代运行时版本、执行轨迹、首偏离点与清理证据。
练习
小结
- script元素:在HTML中声明脚本资源、脚本类型和装载执行策略的元素。
- defer:让外部经典脚本并行下载并在文档解析完成后按文档顺序执行的属性。
- async:让独立外部脚本下载完成后尽快执行且不保证彼此顺序的属性。
- 动态脚本:由运行中代码创建并插入文档、其装载时序需显式管理的脚本元素。
- 文档模式:影响浏览器布局和部分脚本兼容行为的HTML解析兼容模式。
- 六阶段机制链已经映射到正常、边界、失败与恢复证据。
- 官方目录逐项追踪,现代补充不会冒充原书正式分节。