A01 认识 JavaScript 与运行环境
厘清JavaScript语言核心与宿主环境的边界,对比浏览器与Node.js的搭建、三种脚本引入方式差异及调试入口。
- 语言核心与宿主能力分离,document与process等报错应先判断运行环境
- 新项目默认使用type="module",模块脚本自带延迟执行且有独立作用域
- 模块脚本必须经http加载,file://协议会被跨源策略拦截
- defer保证经典脚本在DOM就绪后按文档顺序执行
- Node.js中import报错需改用.mjs后缀或声明"type":"module"
A01 认识 JavaScript 与运行环境
摘要:JavaScript 是在宿主环境中执行的语言,浏览器与 Node.js 提供不同的外部接口,语言本身保持一致。脚本通过
<script>接入页面,type="module"会改变加载时机与作用域。本文给出两种运行环境的搭建、三种引入方式的差异与调试入口,为后续所有示例提供统一环境。
关键词:JavaScript,宿主环境,script 标签,模块,控制台
所属:frontend/js / A-入门 | 上一篇:A00-总结 | 下一篇:A02-变量与数据类型
1 引言
同一个函数在浏览器里能操作 DOM,在 Node.js 里能读写文件,语言语法却完全相同。差异来自宿主环境(host environment,为脚本提供全局对象与外部能力的运行时),不来自语言。
本文解决三个问题:脚本在哪里执行、如何接入页面、出错时从哪里看。范围见表 1-1。
| 项 | 本文覆盖 | 本文不覆盖 |
|---|---|---|
| 环境 | 浏览器控制台、Node.js 命令行 | 打包器与框架 |
| 引入 | 内联脚本、script 标签、模块脚本 |
按需加载与分包策略(C05) |
| 调试 | 控制台日志、断点、报错定位 | 性能剖析(C03) |
2 预备知识
| 项 | 要求 | 核对方式 |
|---|---|---|
| 浏览器 | Chrome 130+,开发者工具可打开 | F12 后 Console 面板可输入 |
| Node.js | 20 及以上 | node -v 输出版本号 |
| 编辑器 | VS Code 或同类,支持 JavaScript 语法高亮 | 打开 .js 文件有高亮 |
| 前置 | HTML A03 | 能写完整 HTML 结构 |
| 素材 | 一个可运行页面 | 含容器元素即可 |
3 原理与实现
3.1 语言与宿主的关系
语言核心只提供语法、类型与内置对象;页面、文件、网络由宿主注入,如图 3-1 所示。
flowchart LR
A["JavaScript 语言核心<br/>语法·类型·Array·Object"] --> B["浏览器宿主<br/>document·window·fetch"]
A --> C["Node.js 宿主<br/>fs·process·http"]
B --> D["页面交互"]
C --> E["服务端与脚本工具"]
图 3-1 语言核心与两类宿主的能力边界
图上可见:
Array、Promise两边都有,document只有浏览器有,process只有 Node.js 有。写错宿主是「document is not defined」的唯一原因。
3.2 三种引入方式
<!-- 运行环境:Chrome 130+;三种方式依次验证加载时机 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>引入方式</title>
<script src="./scripts/inline-defer.js" defer></script>
<script type="module" src="./scripts/module.js"></script>
</head>
<body>
<h1 id="title">脚本引入</h1>
<script>
console.log('[inline]', document.getElementById('title').textContent);
</script>
</body>
</html>
// scripts/inline-defer.js;运行环境:Chrome 130+
console.log('[defer]', document.getElementById('title')?.textContent ?? 'DOM 尚未就绪');
// scripts/module.js;运行环境:Chrome 130+;需通过 http 访问,file 协议会被拦截
import { greet } from './greet.js';
console.log('[module]', greet('模块'));
// scripts/greet.js;运行环境:Chrome 130+
export function greet(name) {
return `hello ${name}`;
}
三种方式的差异见表 3-1。
| 方式 | 写法 | 执行时机 | 作用域 | 适用场景 |
|---|---|---|---|---|
| 内联脚本 | <script>...</script> |
解析到该位置立即执行 | 全局 | 调试片段,不长期保留 |
| 经典外链 | <script src> 默认 |
下载完成后阻塞解析 | 全局 | 老项目、无模块环境 |
| 经典外链加 defer | <script src defer> |
文档解析完成后按序执行 | 全局 | 需要 DOM 且不需模块 |
| 模块脚本 | <script type="module"> |
解析完成后执行,默认延迟 | 模块独立 | 新项目默认选择 |
三条规则:新项目一律用 type="module";模块脚本无 defer 也延迟执行,不要重复添加;模块脚本必须经 http 加载,直接双击 file:// 会被跨源策略拦截。
3.3 Node.js 运行方式
# 运行环境:Node.js 20 及以上;执行目录为项目根
node scripts/greet.js
// scripts/greet.js 末尾追加,用于命令行验证;Node.js 20+
console.log(greet('Node'));
预期输出:hello Node。若报 Cannot use import statement outside a module,说明文件后缀为 .js 而目录未声明模块类型,将文件名改为 .mjs 或在 package.json 中加 "type": "module"。
4 验证与讨论
- 用本地服务器打开页面(
npx serve .),确认控制台依次出现[defer]、[module]、[inline]。 - 删除
defer属性,确认先出现DOM 尚未就绪,再出现标题文本。 - 用
file://直接打开页面,确认模块脚本报 CORS 错误而经典脚本正常。 - 执行
node scripts/greet.js,确认命令行输出与服务端能力可用。
| 检查项 | 预期结果 | 说明 |
|---|---|---|
| defer 顺序 | 按文档顺序执行 | defer 保证顺序 |
| 模块延迟 | 无需 defer 也能拿到 DOM |
模块默认延迟 |
| 模块隔离 | 模块内 var 不挂到 window |
模块有独立作用域 |
| Node 可用 | 输出 hello Node |
宿主差异不影响语言核心 |
讨论与局限。 模块脚本的加载顺序与执行顺序一致,但多个模块的下载是并行的;文件协议下模块被拦截是规范要求,不是浏览器缺陷。另,本章不涉及热更新与构建产物替换,见 C05。
5 常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
Cannot use import statement |
经典脚本中写了 import |
改用 type="module" |
Failed to load module script |
以 file:// 打开页面 |
启动本地服务器 |
document is not defined |
在 Node.js 中操作 DOM | 浏览器专用代码放到页面侧 |
xxx is not defined |
变量未声明或拼写不一致 | 控制台核对名字,启用严格模式 |
| 控制台没有任何输出 | 脚本 404 或语法错误 | Network 面板看状态码,Console 看红字 |
6 结论
| 序号 | 结论 | 依据 |
|---|---|---|
| 1 | 语言核心与宿主能力分离,报错先分环境 | 图 3-1 |
| 2 | 新项目默认用模块脚本 | 表 3-1 |
| 3 | 模块脚本需要 http 环境 | 4 节步骤 3 |
| 4 | defer 解决 DOM 就绪与执行顺序 |
表 3-1 |
- 下一篇:A02-变量与数据类型
- 返回:A00-总结 | 科目 README
参考文献
[1] MDN Web Docs · JavaScript 第一步,https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps(访问于 2026-10-31)
[2] ECMAScript Language Specification,ECMA-262,https://tc39.es/ecma262/(访问于 2026-10-31)

评论 0
还没有评论,快来抢沙发吧~