Skip to content

DRAFT 《现代 JavaScript 教程》前端基础系列 02:语言入门——变量、数据类型与基础交互

约 7677 字大约 26 分钟

2026-04-17

本篇是 JavaScript 语言的基础入门,主要为你搭建语言认知的骨架,涵盖脚本引入、代码结构、变量声明、数据类型以及最基础的浏览器交互弹窗。我们将通过大量实例和底层原理解析,带你写下第一行“现代”的 JavaScript 代码。

【本篇核心收获】

  • 掌握在 HTML 中引入 JavaScript 的多种标准姿势与最佳实践。
  • 理解 JS 的代码结构、分号机制及严格模式 ("use strict") 的核心意义。
  • 深入浅出变量 (let / const) 与内存的映射关系及命名规范。
  • 掌握 JS 的 8 种基础数据类型及其实际应用场景。
  • 学会使用 alertpromptconfirm 进行基础的用户交互操作。

2.1 Hello, world:你的第一行代码

背景:在深入学习语言本身之前,我们需要一个工作环境来运行脚本。浏览器是目前最直观、最容易上手的选择。

<script> 标签

你可以使用 <script> 标签将 JavaScript 程序插入到 HTML 文档的任意位置。

<!DOCTYPE HTML>
<html>
<body>
  <p>script 标签之前...</p>
  <!-- 当浏览器解析到 script 标签时,内部的 JS 代码会自动运行 -->
  <script>
    alert('Hello, world!');
  </script>
  <p>...script 标签之后</p>
</body>
</html>

现代标记的演变

在老旧代码中,你可能会看到以下两个现在已经废弃或改变含义的特性(attribute),对比现状如下:

特性代码示例现状与建议
type<script type="text/javascript">无需再写。老旧 HTML4 标准需要,现代标准中仅在引入 JS 模块(ES Modules)时才具有特殊用途。
language<script language="...">已完全废弃。过去用于指定脚本语言,现在默认就是 JavaScript,写了毫无意义。

避坑提示:古老的注释代码

在一些极度老旧的教程中,可能还会把代码包裹在 HTML 注释里:

<script type="text/javascript"><!--
    // 这里的代码...
//--></script>

这是为了防止“上古时期”不支持 <script> 标签的浏览器把代码当成纯文本暴露在页面上。最近 15 年发布的浏览器都支持该标签,这种写法属于“老掉牙”的历史遗留物,日常开发中绝对不要使用

外部脚本的引入

当你的 JavaScript 代码量逐渐变大时,强烈推荐将其放入一个单独的 .js 文件中。
使用 <script>src 特性即可引入外部文件:

<!-- 1. 绝对路径引入(从网站根目录开始计算) -->
<script src="/path/to/script.js"></script>
<!-- 2. 相对路径引入(等同于 ./script.js,表示当前目录下的 script.js) -->
<script src="script.js"></script>
<!-- 3. 完整 URL 引入(通常用于加载第三方库,如公共 CDN 节点资源) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

如果有多份脚本,需要依次使用多个标签:

<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>

拆分独立文件的核心优势
浏览器会下载独立脚本文件并保存到 缓存(Cache) 中。当后续其他页面再用到同一份脚本时,会直接从缓存读取而无需重新请求,极大节省流量并提升页面加载速度。

⚠️****避坑提示:严禁混用 src 特性和内部代码!
如果一个 <script> 标签设置了 src 属性,那么标签内部包裹的 JS 代码将会被浏览器完全忽略

<!-- ❌ 错误示范:alert 代码将不会执行 -->
<script src="file.js">
  alert(1); 
</script>

```html
<!-- ✅ 正确示范:拆分为两个独立标签 -->
<script src="file.js"></script>

【任务(练习题)】

任务 1:显示一个提示语

重要程度:5
创建一个页面,然后显示一个消息 “I’m JavaScript!”。在沙箱中或者在你的硬盘上做这件事都无所谓,只要确保它能运行起来。

解决方案:

<!DOCTYPE html>
<html>
<body>
  <script>
    // 使用 alert 弹出消息对话框
    alert( "I'm JavaScript!" );
  </script>
</body>
</html>

任务 2:使用外部的脚本显示一个提示语

重要程度:5
打开前一个任务“显示一个提示语”的答案。将脚本的内容提取到一个外部的 alert.js 文件中,放置在相同的文件夹中。打开页面,确保它能够工作。

解决方案:
HTML 页面代码:

<!DOCTYPE html>
<html>
<body>
  <!-- 引入同目录下的外部脚本 alert.js -->
  <script src="alert.js"></script>
</body>
</html>

同一个文件夹中的 alert.js 文件:

// alert.js 文件内容
alert("I'm JavaScript!");

小结:通过 <script> 标签内联代码,或通过 src 属性引入外部文件,是让 JavaScript 在浏览器中跑起来的标准入口。


2.2 代码结构:语句与注释的艺术

认知:了解构建代码块的最小单元——“语句”,以及如何用注释解释它们,是写出高可读性代码的第一步。

语句(Statements)

语句是执行行为(action)的语法结构和命令。
例如 alert('Hello, world!') 就是一条可以用来显示消息的语句。你可以在代码中编写任意数量的语句,语句之间使用分号 ; 相互分割。

为了提高代码的可读性,强烈建议每条语句独占一行

// 清晰易读的排版风格
alert('Hello');
alert('World');

分号的“潜规则”

在大部分情况下,如果存在换行符,你可以省略分号。JavaScript 会把换行符理解为“隐式的分号”,这种机制在底层被称为 自动插入分号(Automatic Semicolon Insertion, ASI)。

// 可以正常运行,JS 引擎会在换行处自动补充分号
alert('Hello')
alert('World')

⚠️****避坑提示:换行绝不等于一定插入分号!

如果一行以加号 + 等不完整的表达式结尾,JS 就不会把它当做一行语句的结束,也就不会插入分号:

// JS 认为这是一个连续的加法表达式,最终正常输出 6
alert(3 +
1
+ 2);

更危险的情况是:引擎无法确定是否需要分号。
来看一个引发异常的真实案例:

alert("Hello")

[1, 2].forEach(alert);

如果你运行这段代码,它只会显示 Hello 并随后报错崩溃。因为 JS 引擎并没有假设在方括号 [...] 前有一个分号,它错误地把两行代码强行合并为了单条语句:

// 这是 JS 引擎眼里的错误代码结构
alert("Hello")[1, 2].forEach(alert);

这会导致完全不符合预期的执行逻辑。

最佳实践:不要完全依赖语言的自动分号插入机制,尤其对新手而言,必须养成在语句末尾显式添加分号的习惯!这是社区被广泛采用的稳妥规范。

注释:给未来的自己留的信

随着程序逻辑变复杂,为代码添加注释来描述“它做了什么”和“为什么要这样做”变得至关重要。注释不会影响代码的执行(引擎会直接忽略它们)。

单行注释:使用双斜杠 // 开始。

// 这行注释独占一行
alert('Hello'); 

alert('World'); // 这行注释跟随在语句末尾

多行注释:使用 /* 开始,并以 */ 结束。

/* 
  这是一个多行注释的例子
  它可以跨越任意多行,非常适合写大段的功能说明
*/
alert('Hello');

效率提升:大多数主流编辑器都支持快捷键。例如 Ctrl + / (Mac 为 Cmd + /) 用于切换单行注释,Ctrl + Shift + / (Mac 为 Option + Cmd + /) 用于选中代码块进行多行注释包裹。

⚠️****避坑提示:绝不支持注释嵌套!
千万不要在 /*...*/ 内部再去嵌套另外一层 /*...*/,这会导致解析被强行截断,直接引发语法错误!

/*
  /* 嵌套多行注释会导致下方代码报语法错误 ?!? */
*/
alert( 'World' );

小结:每一条独立指令用分号结尾是专业开发者的良好素养,而详尽且无嵌套的注释则是保证代码长久可维护性的基石。


2.3 现代模式:"use strict"

背景:在 2009 年的 ES5 标准出现之前,JavaScript 不断添加新特性,但为了兼容旧代码,一些存在缺陷和不完善的设计依然被永久保留了下来。ES5 为了解决这个问题并规范语法,引入了“现代模式”。

启用严格模式

要激活这套修补了历史缺陷、容错率更低的现代特性,你需要使用一个特殊的指令:"use strict"(或者 'use strict')。

放置位置非常严格:它必须被放置在整个脚本文件的最顶部,或者某个函数体的最开头(此时只对该函数内生效,通常我们选择对全局脚本生效)。

"use strict";

// 下面的代码将以标准的“现代”模式运行
...

⚠️****避坑提示:必须置顶,没有回头路

  1. 如果 "use strict" 上方出现了除注释之外的任何其他代码,它都将会被引擎静默忽略,严格模式启用失败。
alert("some code");
// ❌ 下面的 "use strict" 被彻底忽略了,因为它不在最顶部
"use strict";
  1. 语言底层没有提供诸如 "no use strict" 这样的反悔指令。一旦开启了严格模式,当前脚本就无法再退回到默认模式。

浏览器控制台中的严格模式

在使用浏览器的开发者工具(DevTools)执行片段代码时,请注意它是默认不启用严格模式的。
你可以通过以下方式在控制台中强制启用:

  1. 搭配使用 Shift+Enter 按键输入多行代码,把 'use strict'; 写在第一行。
  2. (一种有点丑但极其稳妥的老派做法)使用自执行函数包装器:
(function() {
  'use strict';
  // ...把你的测试代码写在这里...
})()

现代开发还需要手动写 "use strict" 吗?

在现代的 JavaScript 工程开发中,如果我们使用了 class(类)或者 module(模块)(这些高级结构会在本教程后续章节讲到),它们是会自动启用严格模式的。因此,在使用它们时你无需再手动添加指令。
但在当前的初期学习阶段,建议始终在所有脚本顶部加上这行代码。后续本教程的所有示例如果没有特殊说明,也都默认在严格模式下运行。

小结"use strict" 是开启 JavaScript 规范化现代特性的钥匙,将其置于脚本顶端,能有效帮你避开许多老旧语法的“暗坑”。


2.4 变量:数据的“命名存储”

认知:无论是电商网站存放的购物车商品,还是聊天应用的用户消息,都需要被临时保存在内存里。变量(Variable)就是用来给这些动态数据贴上名字的“收纳盒”。

声明与赋值

在现代 JavaScript 中,我们使用 let 关键字来创建一个变量(这个过程被称为声明定义)。

let message; // 声明了一个名称为 "message" 的空变量
message = 'Hello'; // 赋值运算:将字符串数据装入这个变量中

为了让代码更简洁紧凑,我们可以将声明和赋值合并在同一行中:

let message = 'Hello!'; // 定义变量并立即赋初值
alert(message); // 显示该变量内容:Hello!

虽然语法上允许在一行内使用逗号声明多个变量,但为了后期极佳的可读性,强烈建议一行只声明一个变量

// ✅ 推荐做法:结构清晰,易于阅读和排错
let user = 'John';
let age = 25;
let message = 'Hello';

(大白话解释):你可以把变量想象成一个贴着唯一名称标签的“数据盒子”。例如 let message; 是造了个空盒子贴上 message 标签;message = 'Hello!'; 则是把数据塞了进去。

既然叫“变”量,意味着盒子里装的东西想更换多少次都可以:

let message = 'Hello!';
message = 'World!'; // 重新赋值

当新值放入时,盒子里的旧数据就会被直接覆盖清除(如图2所示):

历史遗留的var
在阅读老旧脚本或网上的旧资料时,你常会看到用 var 代替 let 声明变量(如 var message = 'Hello';)。它属于老派做法,行为机制上存在一些容易让人困惑的区别,现阶段请统一认准并使用 let

⚠️****避坑提示:禁止使用 let 重复声明
在同一个作用域范围内,一个变量只能被 let 声明一次,重复声明会导致崩溃级别的语法错误:

let message = "This";
// ❌ 报错:SyntaxError: 'message' has already been declared
let message = "That";

常量(const

当你能百分之百确定某个变量的值永远不会改变时,请使用 const 关键字来声明常数(常量):

const myBirthday = '18.04.1982';
// ❌ 报错:绝不能对常量进行重新赋值操作
myBirthday = '01.01.2001';

使用 const 不仅能从机制上防止数据被意外篡改,还能清晰地向阅读代码的队友传达“这个值是固定的”这一重要事实。

大写常量 vs 常规常量
在团队规范中,我们常把常量分为两类:

  • 大写字母加下划线命名(如 COLOR_RED):特指在代码执行前就已经确定的“硬编码(hard-coded)”值。作为别名,它比直接写一长串十六进制色值或魔法数字好记且不易输错。
  • 常规小写驼峰命名(如 pageLoadTime):用于虽然在运行后不会改变(需用 const 锁定),但它的值是在程序运行时动态“计算”出来的。
// 执行前已知的硬编码值,统统大写!
const COLOR_ORANGE = "#FF7F00"; 
let color = COLOR_ORANGE;

// 运行时才能计算确定的常量,常规驼峰命名!
const pageLoadTime = /* 获取网页真实加载时间的计算逻辑 */;

变量命名硬性规则与软性规范

在 JavaScript 中命名变量必须满足两大“硬限制”:

  1. 变量名称仅允许包含:字母、数字、符号 $_
  2. 首字符绝对不能是数字(例如 1a 是非法的)。

(冷知识):美元符号 $ 和下划线 _ 除了形状不同,和普通字母没有任何区别,let $ = 1; 也是完全合法的。另外,JS 严格区分大小写,appleAPPLE 是两个互不干扰的变量。

除了必须遵守的硬规则,还有区分菜鸟与老鸟的“软规范”:

  • 推崇驼峰式命名法(camelCase):词与词拼接时,除首单词外,后续每个单词首字母大写(如 myVeryLongName)。
  • 避开保留字:不能用语言底层的关键词命名,如 let, class, return, function
  • 见名知意,杜绝废话:变量名必须清晰描述其存储的数据。避免诸如 abc 或意义空洞的 datavalue。推荐像 userNameshoppingCart 这样具象的词。
  • 尽量只用英文:虽然底层允许用中文(如 let 我 = '...'),但为了接轨国际和团队代码的一致性,请强制使用英文命名。

(避坑提示):不要犯懒!宁愿多花三秒钟额外声明几个名字精准的新变量,也绝对不要把一个叫 data 的变量像垃圾桶一样一会装字符串一会装数字,这种行为会在后期代码调试时让你痛不欲生。

【任务(练习题)】

任务 1:使用变量

重要程度:2

  1. 声明两个变量:adminname
  2. 将值 "John" 赋给 name
  3. name 变量中拷贝其值给 admin
  4. 使用 alert 显示 admin 的值(必须输出 "John")。

解决方案:

let admin, name; // 1. 一次声明两个变量
name = "John";   // 2. 赋值
admin = name;    // 3. 内存数据拷贝,现在 admin 盒子里装的也是 "John"
alert(admin);    // 4. 显示

任务 2:给出正确的名字

重要程度:3

  1. 使用我们的星球的名字创建一个变量。你会怎么命名这个变量?
  2. 创建一个变量来存储当前浏览者的名字。你会怎么命名这个变量?

解决方案:

// 1. 代表我们星球的变量,名字越具象精确越好,避免太简短产生歧义
let ourPlanetName = "Earth"; 

// 2. 网站当前访问者的名字
let currentUserName = "John";

善用现代代码编辑器的自动补全功能,多打几个字母换取变量名极佳的自解释性是十分划算的。

任务 3:大写的常量?

重要程度:4
检查下面的代码:

const birthday = '18.04.1982';
const age = someCode(birthday);

对于 birthday 使用大写方式正确吗?那么 age 呢?或者两者都用大写?

解决方案:
birthday 是一个“硬编码”常量,在代码编写阶段就能完全确定其真实值,因此可以且强烈推荐使用大写别名:const BIRTHDAY = '18.04.1982';
相反,对照组的 age 是在程序运行时通过隐藏逻辑实时计算得出的。虽然被赋予初始值后在此次代码执行期间不再改变(符合 const 定义),但它具备随时间变化的计算可变性,因此不属于硬编码,应该继续保持小写驼峰:const age = someCode(BIRTHDAY);

小结:合理利用 let(掌控可变状态)与 const(锁定不变量),并通过团队共识的驼峰规范给每一个数据“盒子”贴上见名知意的精准标签。


2.5 数据类型:JS 的 8 种基础基石

认知:JavaScript 是一门典型的“动态类型”语言。这意味着你定义的变量并没有被限制为某个固定的类型,它上一秒可以存字符串,下一秒立刻就能无缝切换去存储数字。搞清基础的 8 种数据类型,是明白程序真正在处理什么对象的大前提。

JS 中共有 8 种基本的数据类型(细分为 7 种“原始类型”和 1 种“引用/复杂类型”)。

1. Number(数字类型)

既代表普通的整数,也代表浮点数。

let n = 123;     // 整数
n = 12.345;      // 浮点数

除了常规的数字能进行常规的加减乘除外,Number 类型还收编了三个“特殊的数值(special numeric values)”:

  • Infinity (正无穷) / -Infinity (负无穷):比如 1 / 0 计算得出的结果,代表比任何数字都大的值。
  • NaN (Not a Number):代表数学计算过程发生错误,或者执行了未定义的操作。比如让文本去除以数字:"not a number" / 2

特点:在 JavaScript 中做数学运算绝对是极其安全的,程序永远不会因为一个致命的数学错误(比如最经典的除以 0 操作)而导致崩溃“死亡”。最坏的情况,你也仅仅只是得到一个 NaN。注意,NaN 具有极强的“粘性”,任何牵扯到 NaN 的进一步运算,其结果必定还是 NaN

2. BigInt(大整数类型)

受限于底层架构的固定 64 位双精度浮点数存储机制,JS 里的常规 Number 类型只能安全精确地表示在 -(2^53 - 1)(2^53 - 1) 范围内的整数。如果超出这个范围,极易出现末尾精度丢失的问题。
当我们身处密码学开发或需要处理微秒级别高精度时间戳的场景时,我们会在数字的末尾加上一个字母 n 来创造一个 BigInt 类型,用以容纳任意长度的超大整数:

// 尾部的 "n" 标志着这是无上限的 BigInt 类型
const bigInt = 1234567890123456789012345678901234567890n;

(注意:旧版 IE 完全不支持 BigInt,主流现代浏览器已全面兼容)

3. String(字符串类型)

在 C 和 Java 中,单字符有特殊的 char 类型,但在 JS 中没有!只有统一的 String 类型。
在 JavaScript 中,字符串必须被三种类型的引号包裹:双引号 "..."、单引号 '...'、以及反引号 `...`

let str = "Hello";
let str2 = 'Single quotes are ok too'; // 单双引号在 JS 中毫无差异,随你喜欢

// 反引号是强大的扩展版引号,允许在内部直接嵌入变量或动态表达式
let name = "John";
let phrase = `can embed another ${name}`; // 结果:can embed another John
alert( `the result is ${1 + 2}` ); // 结果:the result is 3

(大白话解释):反引号就像一个能通电的排插,而内部的 ${...} 就像插孔。一旦遇到插孔,JS 引擎就会把孔内的代码执行计算完毕后,转化成文字无缝拼接到大段字符串中,这是普通的单双引号绝对办不到的魔法。

4. Boolean(布尔逻辑类型)

极为简单纯粹,整个类型下仅包含两个固定的值:true (真 / 是 / 对) 和 false (假 / 否 / 错)。
常用来存储逻辑开关状态,或者直接作为逻辑比较运算的结果诞生:

let nameFieldChecked = true; // 状态位:字段被勾选了
let isGreater = 4 > 1; // 进行数学比较运算,结果自动产生 true

5. null(空值)

这是一个非常特殊的原始类型,它自成一派,旗下只包含一个独苗值:null
和其他严格语言里的空指针概念不同,在 JS 中,null 仅仅是一个代表**“无”、“空”或“值未知”**的特殊标记物。

let age = null; // 明确告诉外界:目前不知道 age 是多少,此处刻意留空

6. undefined(未定义值)

同样是自成一派,只包含 undefined 这个单一的值。
它的标准定义是:“变量虽已被声明,但还未被赋予任何实际的值”

let age;
alert(age); // 引擎自动赋初始默认值,弹出 "undefined"

(规范要求):技术上虽允许,但强烈建议永远不要手动去把一个变量赋值为 undefined。如果想人为清空一个变量的值,请使用 null。应当把 undefined 纯粹地保留作为 JS 引擎判定变量未被初始化的专属警告标记。

7. Object(对象类型)与 Symbol

  • object 属于非原始数据类型(复杂/引用类型)。前面的 6 种原始类型都太过单薄,每次只能存一个单一独立的数据。而 object 则可以用来构建更复杂的数据集合与结构实体(这也是为什么面向“对象”编程如此重要,我们会在后面完整章节详述)。
  • symbol 类型则主要配合对象使用,用于生成全宇宙独一无二的专属标识符。

typeof 运算符:数据类型探测器

typeof 是一个内建操作符,功能就是返回其后面紧跟的参数的具体数据类型(以全小写字符串的形式)。在做不同类型的分类处理或是类型前置检验时极其好用。
无论是写成空格分割的 typeof x 还是套括号的 typeof(x),两者效果一模一样(括号单纯是数学运算里用于改变优先级的括号,并不是因为它是函数)。

typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (Math 是语言内建的功能提供对象)

⚠️****历史遗留的两大 typeof 异常现象:

  1. typeof null 的返回结果居然是 "object"。这是官方亲自盖章承认的语言早期严重 Bug,但为了千万老网站的向下兼容性而永远保留了下来。请死死记住:null 绝对不是 object,它就是属于它自己的特殊类型!
  2. typeof alert 的返回结果是 "function"。严格从语言底层讲,JS 根本没有专门的 function 基础类型(所有函数本质上都是 object),但 typeof 为了方便开发者做出了这一极其便利的特殊细分处理。

【任务(练习题)】

任务 1:字符串的反引号

重要程度:5
仔细阅读并推断,下面的脚本会依次弹出输出什么结果?

let name = "Ilya";

alert( `hello ${1}` ); // ?
alert( `hello ${"name"}` ); // ?
alert( `hello ${name}` ); // ?

解决方案:
反引号的作用就是将包装在插孔 ${...} 中的表达式强行计算并嵌入到外层字符串内。

  1. 第一个是单纯包裹了数字表达式:输出 hello 1
  2. 第二个包裹的是一对双引号包围的死文本 "name",它不是变量,所以原样输出字符串:输出 hello name
  3. 第三个包裹的是一个活生生的变量,于是触发计算查找到上方的值,成功嵌入:输出 hello Ilya

小结:牢记 7 种原始基本类型(Number, BigInt, String, Boolean, null, undefined, Symbol)和唯一的大神级复杂类型(Object)。在排错遇到瓶颈时,熟练抛出 typeof 往往能一刀切中要害。


2.6 交互:alert、prompt 和 confirm

背景:在学习前端复杂的 DOM 树和炫酷 CSS 动画之前,我们需要一种最简易粗暴的手段在浏览器里进行变量的输入与输出测试。这三个内建的交互函数完美充当了我们初期的教学伴侣。

它们都有一个共同的霸道特征——弹出的窗口被称为 模态窗(modal)。一旦模态窗现身,页面代码的执行会瞬间暂停,并且全面封锁用户与页面其余部分的交互(你无法点击底下页面的任何按钮),直到用户将这块“挡路石”彻底处理完毕。

alert(单纯的信息弹窗)

非常直白,单纯在屏幕上呼出一个消息框展示文本,并强制用户点击 “确定(OK)” 后才能放行。

alert("Hello");

prompt(获取用户输入)

弹出一个带有输入框的质问窗口,要求用户通过键盘录入信息。
语法规则result = prompt(title, [default]);

  • title:核心必填参数,显示给用户看的问题或者引导文本。
  • default:由方括号包裹代表可选的第二个参数。用于提前塞进输入框占位的默认初始值。
// 获取的输入结果会被赋值给等号左侧的 age 变量
let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`); // 如果没改,直接输出 You are 100 years old!

如果用户在这个弹窗下点击了“取消”按钮,或者是眼疾手快按下了键盘的 Esc 键强制解除,prompt 拿不到输入数据,就会绝望地返回特殊的空值 null

(避坑提示):老旧傲娇的 Internet Explorer 浏览器如果在调用时你偷懒没有传递第二个 default 参数,它会在你的输入框里极其违和地直接填入字符串 "undefined"。为了全平台完美兼容的一致体验,建议永远随手补齐第二个参数的空位:

let test = prompt("Test", ''); // 塞个空字符串进去,给 IE 一个面子

confirm(是非抉择弹窗)

显示一个携带了你的 question 提问,外加 确定 和 取消 左右两大护法按钮的裁判模态窗口。
语法规则result = confirm(question);

  • 点击“确定”,斩钉截铁地返回布尔值 true
  • 点击“取消”或者按下逃生键 Esc,返回布尔值 false
let isBoss = confirm("Are you the boss?");
alert(isBoss); // 只有按下确定按钮,这里才会输出 true

它们的局限性与取舍

上述介绍的三剑客共有两个逃不掉的硬伤限制:

  1. 模态窗口弹出的具体定位坐标完全由浏览器主宰(通常锁死在屏幕正中央)。
  2. 窗口UI界面的美丑、按钮文案的字体等样式完全跟读用户浏览器的品牌和系统版本,开发者完全无权通过 CSS 去篡改和美化它

虽然它们在实际高逼格的商业级项目中往往会被重金手写的精美 UI 组件库所取代,但对于不需要“花里胡哨”的初期脚本调试和极客工具开发而言,这份简单粗暴的代价反而是极佳的优点。

【任务(练习题)】

任务 1:创建一个简单的页面

重要程度:4
创建一个要求用户输入 name,并通过浏览器窗口对键入的内容进行原样输出反馈的 web 页面。

解决方案:

<!DOCTYPE html>
<html>
<body>
  <script>
    'use strict'; // 永远不忘开启现代模式
    
    // 1. 拦截用户并主动询问名字,提供空字符串作为兼容性默认值兜底
    let name = prompt("What is your name?", "");
    
    // 2. 将收获到的变量作为战利品展示出来
    alert(name);
  </script>
</body>
</html>

小结alert(单向霸道通知)、prompt(双向索取文本或 null)、confirm(裁判索取逻辑布尔值)这三个原生 API,低成本地构成了我们初期调试代码时最不可或缺的浏览器交互三剑客。


【本篇核心知识点速记】

  • 无论怎么折腾,一旦 <script src="..."> 引入了外部脚本,标签内部手写的代码就注定会被浏览器无情忽略。
  • 一条独立语句独占一行,且永远不要产生侥幸心理,请在结尾老老实实加上分号 ;
  • 坚持在每一个独立文件的顶部贴上 "use strict";,强迫自己置身于现代语法的严谨约束下。
  • let 用来声明随时准备善变的变量,const 用来声明一锤定音的常量。请坚持使用小驼峰命名法,并且做到见名知意。
  • 8 种数据类型背诵口诀:数字(含扩充的BigInt)、字符串、布尔、空(null)、未定义(undefined)、符号(symbol) 这7类原始大军,外加掌控全局的对象(object)。
  • typeof null === 'object' 这是一个流传千古的底层历史 Bug,切勿把 Bug 当事实。
  • 交互三剑客:alert (单纯展示)、prompt (要你输入)、confirm (要你抉择),使用它们都会绝对阻塞页面其他一切代码与渲染的执行。
贡献者: weew12