云计算百科
云计算领域专业知识百科平台

从普通 script 到 ESM:一文搞懂 JavaScript 模块、IIFE 和 window

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

写前端代码时,我们经常遇到两种用法:

<script src=\”./xxdemo.js\”></script>

import {

hello } from \’./xxdemo.js\’

同样是 JS 文件,为什么加载方式不同?为什么有些库会写 window.xxx,有些库却使用 export?IIFE 又是什么,为什么要让函数定义后立即执行?

1. JS、TS、ESM、npm,分别在说什么?

先分清它们描述的层面:

名称
描述的事情
简单理解
JavaScript,简称 JS 编程语言 编写浏览器执行的逻辑
TypeScript,简称 TS 带类型系统的语言 开发时增加类型检查,通常转换为 JS 后交付
ESM JavaScript 的标准模块机制 用 import 和 export 共享功能
IIFE 一种函数表达式写法 函数定义后立即调用,常用于隔离内部变量
npm 软件包管理和分发 安装依赖、管理版本、发布代码包
Vite、esbuild 等 开发和构建工具 转换源码、处理依赖、生成发布文件

因此,“使用 JS 还是 ESM”并不是两个并列选项。采用 ESM 时,写的仍然可以是 JavaScript。

TypeScript 的类型主要在开发阶段帮助检查代码,不会作为类型检查逻辑自动带到浏览器中。参考:TypeScript 官方入门

2. 普通 script 是怎么使用 JS 的?

本文把没有 type=\”module\” 的 JavaScript 脚本称为“普通脚本”,也叫经典脚本。

例如,一个完整的 HTML 页面可以这样写:

<!DOCTYPE html>
<html lang=\”zh-CN\”>
<head>
<meta charset=\”UTF-8\”>
<title>xxdemo 普通脚本示例</title>
</head>
<body>
<p id=\”output\”></p>

<script>
function hello(name) {


return \’你好,\’ + name
}

document.getElementById(\’output\’).textContent = hello(\’xxdemo\’)
</script>
</body>
</html>

这里的代码由浏览器直接执行。也可以把脚本移到外部文件,再通过 src 加载。

文件以 .js 结尾,并不能说明它是普通脚本还是 ESM。 还要看文件内容,以及它被怎样加载。参考:MDN script 元素

3. window.xxx 是什么?

在浏览器页面里,window 是全局对象。下面的代码给它增加了一个属性:

window.XXDemo = {


hello(name) {


return \’你好,\’ + name
}
}

其他脚本就可以使用:

window.XXDemo.hello(\’xxdemo\’)

在没有同名局部变量遮蔽等情况下,也可以写:

XXDemo.hello(\’xxdemo\’)

把功能集中在 XXDemo 下面,可以避免将许多名字分别放到全局,例如 window.hello、window.reset、window.start。

但 window.xxx 本身不是模块规范。普通脚本可以给它赋值,ESM 也可以给它赋值。

4. IIFE 为什么要立即执行?

IIFE 的全称是 Immediately Invoked Function Expression,中文叫“立即执行函数表达式”。

普通函数往往先定义,再调用:

function start() {


console.

赞(0)
未经允许不得转载:网硕互联帮助中心 » 从普通 script 到 ESM:一文搞懂 JavaScript 模块、IIFE 和 window
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!