全局执行上下文在脚本加载时立即创建,document.ready是dom就绪后触发的回调;前者决定代码运行环境,后者控制dom操作时机,二者分属js引擎机制与浏览器事件机制。

全局执行上下文(Global Execution Context)和 document.ready 不是同一类机制,也不在同一个时间轴上直接比较——前者是 JavaScript 引擎启动时立即创建的运行环境,后者是 DOM 就绪后由浏览器触发的事件回调。关键在于:**脚本代码本身在全局上下文中执行,而 document.ready 的回调函数是在 DOM 构建完成后、被推入任务队列再执行的**。
全局执行上下文什么时候建立?
它在页面加载早期就已存在,具体时机取决于脚本的引入方式:
- 内联
<script></script>:HTML 解析到该标签时,JS 引擎同步创建全局上下文并执行代码;此时 DOM 可能远未构建完成(document.body还为null) - 带
defer的外链脚本:全局上下文在 DOM 解析完毕后、DOMContentLoaded触发前创建并执行 - 带
async或无属性的外链脚本:下载完即创建上下文执行,时机不可控,可能早于或晚于 DOM 构建
document.ready 实际对应什么?
它不是原生 API,而是 jQuery 封装的 DOMContentLoaded 事件的别名(或兼容实现)。它的本质是监听 DOM 树就绪信号,与全局上下文的生命周期无关:
- 回调函数本身在全局上下文中执行,但执行时机被延迟到 DOM 构建完成之后
- 即使你在
中写$(document).ready(...),jQuery 内部也会缓存该回调,等 DOM 就绪后再统一触发 - 它不阻塞 HTML 解析,也不影响全局上下文的创建顺序
常见误判场景
容易混淆的点往往出现在脚本位置和执行依赖上:
- 在
里直接操作document.getElementById失败,不是因为没进全局上下文,而是 DOM 根本还没生成 - 用
document.readyState === 'interactive'判断时,若脚本在底部,可能已进入该状态,无需等待事件 -
$(document).ready()可多次调用且全部执行,是因为 jQuery 维护了一个回调队列;而原生window.onload是赋值覆盖,这是设计差异,不是执行上下文的问题
怎么安全地衔接两者?
多数情况下不需要“衔接”,只需按需选择执行时机:
- 只操作 DOM 结构 → 用
DOMContentLoaded或$(document).ready() - 需要读取图片尺寸、计算布局、依赖 CSS 渲染结果 → 等
window.onload或监听document.readyState === 'complete' - 想尽早初始化逻辑又避免 DOM 访问错误 → 把初始化函数封装好,在
DOMContentLoaded回调里调用,而不是放在全局脚本顶层











