接续上文:Day14——JavaScript 核心知识全解析:变量、类型与操作符深度探秘-CSDN博客
点关注不迷路哟。你的点赞、收藏,一键三连,是我持续更新的动力哟!!!
主页:一位搞嵌入式的 genius-CSDN博客
系列文章专栏:
https://blog.csdn.net/m0_73589512/category_13011829.html
目录
Day15 (前端:JavaScript基础阶段)
1. Number 类型
1. Number 类型基本使用
2. Number 类型的进制表示
3. Number 类型的数字表示范围
4. Number 类型的 isNaN 函数
2. 字符串类型
1. 字符串的三种表示方法
2. 前后的引号类型必须一致
3. 字符串中的转义字符
4. 字符串的属性和方法
5. 知识小结
3. 布尔类型
1. 真假表示
2. 布尔类型基本使用
3. 布尔类型值
4. undefined 类型
1. undefined 类型的特点
2. undefined 类型的打印示例
3. undefined 类型的赋值示例
4. undefined 类型的初始化示例
5. undefined 类型的默认值
6. undefined 类型的注意事项
知识小结
5. Object 类型
1. Object 类型概念
2. Object 类型和 Null 类型的关联与应用
3. Object 类型的核心特性与后续扩展
6. Null 类型
1. Null 类型概念
2. Null 类型的应用与规范
7. Object类型和Null类型知识小结
8. Object 和 Null 类型(补充)
1. 数据类型总结
2. Object 类型详解
3. Null 类型详解
9. 数据类型的转换(梗概介绍)
1. 数据类型的转换定义
2. 数据类型的自动转换(隐式转换)
3. 数据类型的显示转换(显式转换)
4. 知识小结
10. 数据类型转换(String-Number)
一、字符串的转换
1. 其他类型转成字符串
1) 隐式转换
2) 显式转换
二、数字类型的转换
1. 其他类型转成数字类型
1) 隐式转换
2) 显式转换
2. 数字类型转换总结
三、布尔类型转换
1. 隐式转换
2. 显式转换
3. 布尔类型转换总结
11. JavaScript 基础运算符
1. 运算符和运算元
1)运算符
2)运算元
2. 知识小结
12. JavaScript 常见的运算符
1. JavaScript 中运算符
1)算数运算符的使用
2)取余 % 和求幂 ** 的补充说明
2. 知识小结
13. 赋值和链式赋值运算符
1. 赋值运算符
1)赋值运算符的定义
2)链式赋值
3)链式调用的扩展
2. 知识小结
14. 赋值运算符
15. 原地修改
1. 概念与基本使用
2. 运算符简写形式
3. 知识小结
16. 自增、自减
1. 自增自减的概念
2. 自增自减的常用场景
3. 自增运算符的使用
4. 自减运算符的使用
5. 自增自减的注意事项
6. ++ 和 -- 的位置
1. 自增和自减的位置举例
(1)独立使用时的等效性
(2)复合表达式中的区别
(3)实际开发建议
2. 运算符 ++ 和 -- 的位置
(1)术语定义
(2)核心区别:返回值差异
(3)使用场景
(4)记忆要点
7. 知识小结
17. 运算符的优先级
1. 例题:运算符优先级示例
2. 运算符优先级的汇总表
核心注意事项
18. == 和 === 的区别
1. 普通相等性检查(==)的问题:隐式类型转换
(1)核心转换规则与特殊案例
(2)转换机制验证:用 Number() 显式模拟
(3)== 的风险
2. 严格相等运算符(===):无隐式转换,更安全
(1)核心比较规则
(2)示例对比:== vs ===
(3)对应的 “不相等” 运算符
3. 开发建议:优先使用 ===
4. 知识小结
19. 代码执行方式和代码块儿理解
一、分支语句
1. 程序的执行顺序
1)默认执行顺序:顺序执行
2)程序的三种执行方式
3)执行顺序总结
2. 代码块的理解
1)代码块的定义与语法
2)代码块与 “对象字面量” 的区别
3)代码块的核心特征
二、分支语句的预告
20. ECMAScript 标准文档介绍
1. 标准核心信息
2. 文档内容概述
3. 访问注意事项
4. == 操作符比较规则(标准视角)
21. 验证 “内容不一致” 的方法
1. 文档验证的核心逻辑
2. JavaScript 学习的权威资源排序
3. 验证流程(三步确认法)
22. 代码块基础
1. 代码块的定义与必要性
2. 代码块与流程控制的关系
3. 代码块的核心特征
23. 分支语句的实现
1. 生活中的条件判断(代码映射)
2. 什么是分支结构
3. 分支结构的类型(以 if 系列为例)
(1)单分支结构(if 语句)
(2)多分支结构(if-else if-else 语句)
4. 知识小结
24. 分支语句
1. 单分支结构
(1)基本语法与执行逻辑
(2)例题 1:考试成绩判断
(3)例题 2:苹果购买折扣
2. if 语句的细节补充
(1)代码块省略规则
(2)条件判断的隐式转换
3. 知识小结
Day15 (前端:JavaScript基础阶段)
1. Number 类型
Number 类型表示数字类型,可代表整数或浮点数。
1. Number 类型基本使用
数字类型可通过赋值操作存储于变量中,例如:
JavaScript 不区分整数与浮点数,二者均属于 Number 类型。
数字类型支持加减乘除等基础运算,运算符相关内容将在后续章节详细讲解。
Number 类型包含两个特殊值:
-
Infinity(无穷大),可通过 1/0 或直接赋值 Infinity 获得。
-
NaN(Not a Number),表示非数字结果,例如 3 * "ABC" 会返回 NaN,通常由计算错误引发。
2. Number 类型的进制表示
进制类型 | 表示方法 | 示例 | 十进制等价值 |
---|---|---|---|
十进制 | 直接书写数字 | 100 | 100 |
十六进制 | 以 0x 开头 | 0x100 | 256 |
八进制 | 以 0o 开头 | 0o100 | 64 |
二进制 | 以 0b 开头 | 0b100 | 4 |
实际开发中多使用十进制,其他进制仅需了解表示方法。
3. Number 类型的数字表示范围
-
最大值可通过 Number.MAX_VALUE 获取(约 - 79e+308)。
-
最小正数值可通过 Number.MIN_VALUE 获取(约 5e-324),低于此值将自动转为 0。
常量命名规范:常量(不可变值)通常以全大写表示,如 MAX_VALUE。
4. Number 类型的 isNaN 函数
isNaN () 函数用于检测是否为 NaN,例如:
NaN 常见于计算错误场景,实际开发中需避免此类操作。
2. 字符串类型
1. 字符串的三种表示方法
-
双引号表示:使用双引号包裹字符串内容,如
"Hello World"
。在大多数编程语言中都支持这种表示方式,具有更好的兼容性。-
开发习惯:推荐使用双引号,因为大多数编程语言都支持双引号表示字符串,保持代码风格统一。
-
实际案例:
var name = "coderwhy"
,var address = "广州市"
等实际开发中的变量定义。
-
-
单引号表示:使用单引号包裹字符串内容,如
'Hello World'
。在 JavaScript 中与双引号完全等效,但部分语言不支持。-
等效性:在 JavaScript 中单引号和双引号完全等效,如
var message1 = 'Hello World'
和var message2 = "Hello World"
效果相同。 -
项目规范:实际项目中会通过配置工具自动统一引号风格,开发时无需过度纠结选择。
-
-
反引号表示:使用反斜引号包裹字符串内容(键盘 Tab 键上方),如
Hello World
。这是 ES6 新增语法,支持字符串插值和多行字符串。-
特殊功能:支持字符串插值,可以在字符串中嵌入变量或表达式,如 `var message3 = \Hello World,{2 + 3}``。
-
ES6 特性:反引号是 ES6 新增语法,相比传统字符串拼接更简洁直观。
-
2. 前后的引号类型必须一致
一致性要求:字符串开始和结束的引号类型必须相同,不能混用,如"Hello'
是错误的写法。
嵌套解决方案:当字符串内容包含引号时:
-
内容含双引号时使用单引号包裹:
'my name is "coderwhy"'
-
内容含单引号时使用双引号包裹:
"It's a nice day"
-
或者使用反引号:
It's "coderwhy"
3. 字符串中的转义字符
基本概念:使用反斜杠\
对特殊字符进行转义,使其失去特殊含义成为普通字符。
常见转义字符:
-
\'
表示单引号 -
\"
表示双引号 -
\\
表示反斜杠本身 -
\n
表示换行符 -
\t
表示制表符
1)转义字符表示符号 实际应用:var message5 = 'my name \\\' is "coderwhy"'
演示了如何转义字符串中的单引号。 开发注意:在前端开发中较少直接处理转义字符,通常由后端处理好后传给前端展示。
4. 字符串的属性和方法
1)字符串属性
-
length
属性:获取字符串长度,如"Hello World".length
返回 11(包含空格)。 -
访问方式:通过点运算符直接访问属性,不加括号,如
message.length
。
2)字符串操作
-
传统拼接:使用加号运算符连接字符串,如
var infoStr2 = info + nickname
。 -
ES6 模板字符串:推荐使用反引号和
${}
插值语法,如 `var infoStr = \my name is${nickname}``。 -
开发建议:优先使用模板字符串,虽然需要 ES6 支持,但现代工具会自动处理兼容性问题。
5. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
数字类型 | 基本使用方法讲解,后续会补充类相关概念后的高级方法 | 类概念与数字方法的关联性 | ⭐⭐ |
字符串类型 | 三种表示方法(单引号 / 双引号 / 反引号)及使用场景 | 反引号的 ES6 模板字符串特性 | ⭐⭐ |
字符串拼接 | 传统 + 运算符拼接 vs ES6 模板字符串拼接 | 模板字符串的变量嵌入语法${variable} | ⭐⭐ |
转义字符 | 处理字符串中的特殊符号(单 / 双引号、斜杠等) | 斜杠需双重转义\\ | ⭐⭐⭐ |
字符串属性 | .length 获取字符串长度 | 属性访问与方法调用的区别 | ⭐ |
开发规范 | 引号使用偏好说明(双引号跨语言兼容性) | 项目配置自动统一引号格式 | ⭐ |
数据类型转换 | 隐式字符串拼接(数字 + 字符串自动转换) | 类型转换优先级规则 | ⭐ |
3. 布尔类型
字符串类型(string 类型)讲解结束后,接下来学习布尔类型(Boolean 类型)。布尔类型用于表示真(true)和假(false)两种逻辑状态,对于初次接触编程的学习者需要重点理解其逻辑表达特性。
1. 真假表示
在程序开发中,真假的表示可通过自定义规范实现,常见方式包括:
-
数字表示法:用 1 表示真,0 表示假
-
字符串表示法:用 "yes" 表示真,"no" 表示假
不同编程语言采用不同规范,例如 Objective-C 使用 YES/NO 表示真假。JavaScript 专门设计布尔类型统一表示逻辑状态,其设计基于计算机科学的布尔代数原理,且为纪念数学家乔治・布尔。典型应用场景包括:
-
用户登录状态验证(如 isLogin 变量)
-
权限控制判断(如 isAdmin 变量)
2. 布尔类型基本使用
布尔类型在开发中的核心应用表现为:
-
仅包含两个固定值:true(真)和 false(假)
典型使用场景:
-
记录用户登录状态(isLogin = true/false)
-
标识管理员权限(isAdmin = true/false)
-
基本值:仅包含两个值,分别是
true
(真)和false
(假)。 -
变量声明示例:(可参考如下形式)
let isLogin = true; // 表示登录状态为“已登录” let hasPermission = false; // 表示权限状态为“无权限”
-
后续应用:布尔类型是逻辑判断的核心,将在逻辑运算符(如
&&
、||
、!
)、条件语句(如if-else
)中详细使用,用于控制程序流程。
布尔类型命名源于布尔代数体系,计算机底层通过 0/1 实现逻辑运算,现代编程语言普遍采用该类型标准化逻辑表达。
3. 布尔类型值
布尔类型的值严格限定为:
-
true:表示逻辑真值
-
false:表示逻辑假值
4. undefined 类型
1. undefined 类型的特点
-
唯一值:该类型仅有一个特殊值 ——
undefined
,不存在其他取值。 -
默认情况:当变量被声明但未进行初始化(未赋值)时,JavaScript 会自动为其分配默认值
undefined
。
2. undefined 类型的打印示例
-
示例代码:
let age; // 声明变量但未赋值 console.log(age); // 输出:undefined(变量默认值为undefined) console.log(typeof age); // 输出:"undefined"(变量类型为undefined)
-
特殊变量名:避免使用
name
作为演示变量,因为在浏览器环境中,全局变量name
有默认值(空字符串""
),无法体现undefined
的默认特性,推荐使用age
、info
等变量名。
3. undefined 类型的赋值示例
-
不推荐写法:不建议主动将变量赋值为
undefined
(如let score = undefined;
),这不符合良好开发规范。 -
值类型关系:
undefined
具有双重属性 —— 既是一个具体的值,也是一种独立的数据类型。类比理解:123
是 “数字值”,其对应类型是number
;而undefined
这个 “值”,对应的类型也叫undefined
。
4. undefined 类型的初始化示例
-
两种等价写法:
let msg1; // 写法1:仅声明未赋值,默认值为undefined let msg2 = undefined; // 写法2:显式赋值为undefined
-
开发规范:上述两种写法均不符合良好编程习惯,变量声明时应明确初始化(如赋值为空字符串、0 等),而非依赖默认的
undefined
或显式赋值undefined
。
5. undefined 类型的默认值
-
类型验证:未初始化的变量,其值和类型均为
undefined
,可通过
typeof
验证:
let uninitVar; console.log(uninitVar === undefined); // 输出:true(值为undefined) console.log(typeof uninitVar === "undefined"); // 输出:true(类型为undefined)
-
本质特征:
undefined
的核心作用是标记 “变量已声明但未被赋予有效值” 的状态,是 JavaScript 对 “未初始化变量” 的统一默认处理。
6. undefined 类型的注意事项
-
最佳实践:
-
初始化原则:变量定义时必须主动初始化,不应仅声明不赋值(如
let username = "";
而非let username;
)。 -
赋值禁忌:禁止显式将变量赋值为
undefined
,避免混淆 “未初始化” 与 “主动设空” 的语义。
-
-
替代方案:根据变量预期类型,选择合理的初始值:
-
字符串类型变量:初始化为空字符串
""
(如let title = "";
)。 -
数字类型变量:初始化为
0
(如let count = 0;
)。 -
对象类型变量:初始化为
null
(后续对象章节详细讲解,如let user = null;
)。
-
-
危险操作:未初始化的变量属于不规范操作,可能导致逻辑判断错误(如误判
undefined
与其他空值),引发程序意外行为。
知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
undefined 类型 | 1. 唯一值为 undefined ; 2. 未初始化变量的默认值; 3. 既是值也是类型(类型名小写) | 1. 与 null 的区别(后续讲解); 2. 浏览器全局变量 name 的特殊性(默认空字符串) | ⭐⭐ |
变量初始化规范 | 1. 禁止显式赋值 undefined ; 2. 推荐初始化为对应类型空值("" /0 /null ); 3. 未初始化属于危险操作 | 1. 显式 undefined 与隐式未初始化的效果差异(值相同但规范度不同) | ⭐⭐ |
类型系统特性 | 1. 普通值(如 123 )对应固定类型(如 number ); 2. undefined 是 “值与类型同名” 的特殊案例 | 1. 类型名称大小写区分(如 undefined 是值 / 类型名,无大写 Undefined 类型) |
5. Object 类型
1. Object 类型概念
-
特殊类型定位:Object 类型是 JavaScript 中的核心引用类型(也叫复杂类型),区别于仅存储单个值的原始类型(如 string、number、boolean 等)。
-
与原始类型的核心区别:
-
原始类型:仅包含单一数据(如
let name = "手机"
,变量直接存储字符串值); -
Object 类型:可整合一组相关数据,形成 “键值对” 集合(如商品的名称、价格、库存等属性)。
-
-
表示方法:使用花括号
{}
定义对象,内部以 “属性名:属性值” 的格式声明数据,属性间用逗号分隔,示例:
// 电商商品对象,整合名称、价格、库存属性 let phone = {name: "智能手机",price: 3999,stock: 100 };
-
内存分配特性:Object 类型的数据存储在堆内存中,变量实际存储的是 “指向堆内存对象的引用地址”(非对象本身),后续会通过内存图详细讲解引用机制。
2. Object 类型和 Null 类型的关联与应用
-
实际应用场景:以电商网站商品信息管理为例,若用原始类型存储,需定义多个分散变量(如
phoneName
、phonePrice
、phoneStock
),而 Object 类型可通过一个对象整合所有属性,更便于管理。 -
基本语法与属性访问:
-
定义语法:
let 对象名 = { 属性名1: 属性值1, 属性名2: 属性值2, ... }
; -
属性访问:通过 “点语法”
对象名.属性名
获取属性值,示例:
let book = {name: "JavaScript基础",price: 59.9,author: "张三" }; console.log(book.name); // 输出:"JavaScript基础"(访问书名属性) console.log(book.price); // 输出:59.9(访问价格属性)
-
-
控制台查看:打印对象时(如
console.log(book)
),控制台会显示对象的所有自定义属性,以及继承自原型(prototype
)的内置属性(后续讲解原型概念)。
3. Object 类型的核心特性与后续扩展
-
核心特点:
-
用于表示 “数据集合”,将相关属性整合到一个变量中;
-
用
{}
语法定义,属性以键值对形式组织; -
开发优势:相比分散变量,更易维护、传递和修改相关数据(如批量传递商品信息到函数)。
-
-
原始类型的临时包装:当原始类型(如 string)通过点语法访问属性 / 方法时(如
"hello".length
),JavaScript 会临时将其包装成对应对象(如String
对象),访问完成后立即销毁该临时对象,这也是原始类型能调用方法的原因。 -
后续扩展方向:
-
面向对象编程概念(如对象的创建、使用);
-
new
关键字创建对象(如new Object()
); -
ES6 类(
class
)语法(对象的模板); -
原型(
prototype
)与继承(对象间的属性 / 方法复用)。
-
6. Null 类型
1. Null 类型概念
-
基本定义:Null 类型是原始类型的一种,仅有一个特殊值
null
,专门用于表示 “对象为空” 的状态(即变量本应指向对象,但当前无有效对象可指向)。 -
内存原理:
-
若变量赋值为空对象
{}
,JavaScript 会在堆内存中创建一个空对象结构,变量存储指向该结构的引用; -
若变量赋值为
null
,变量会指向内存地址0x0
(空地址),不会在堆内存中创建任何对象结构,避免不必要的内存开销。
-
-
类型检测特性:使用
typeof
检测
null
时,会返回
"object"
,这是 JavaScript 的历史遗留 bug(早期引擎设计时将
null
归为 “空对象引用”),需特殊记忆(实际
null
是原始类型,非对象),示例:
console.log(typeof null); // 输出:"object"(历史bug,非实际类型)
2. Null 类型的应用与规范
-
初始化规范:当变量预期存储对象(如后续要赋值的商品信息、用户数据),但初始值不确定时,推荐赋值为
null
,而非空对象{}:
-
推荐:
let product = null;
(后续可赋值为具体商品对象); -
不推荐:
let product = {};
(会创建空对象,占用堆内存,且可能误导逻辑判断)。
-
-
布尔转换特性:在逻辑判断中,
null会转为false,而空对象{}会转为true,这是两者的关键区别,需避免因混淆导致逻辑错误:
if (null) {console.log("执行"); // 不执行(null转false) } if ({}) {console.log("执行"); // 执行(空对象转true) }
-
与
undefined
的区别:类型 核心语义 赋值方式 应用场景 undefined 变量 “未初始化” 的默认状态 隐式(引擎自动赋值) 变量声明未赋值时的默认值 null 变量 “主动标记为空对象” 显式(开发者主动赋值) 对象变量初始化、清空引用 -
示例对比:
let uninitVar; // 隐式为undefined(未初始化) let emptyObj = null; // 显式为null(主动标记空对象)
-
-
典型应用场景:
-
异步数据加载前:如请求接口获取用户信息前,
user
变量初始化为null
,加载成功后赋值为用户对象; -
可选对象参数:函数参数若为可选对象,默认值设为
null
(如function getProduct(id, options = null) {}
); -
对象引用清除:当不再需要某个对象时,赋值为
null
,帮助垃圾回收机制释放内存(如user = null;
)。
-
7. Object类型和Null类型知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
undefined 类型 | 变量声明未初始化时的默认值,隐式赋值 | 与null 的语义区别:undefined 是 “未赋值”,null 是 “空对象” | ⭐⭐ |
原始类型总结 | 共 5 种:number/string/boolean/undefined/null;null 虽typeof 显式 object,但归为原始类型 | null 的类型归类争议(历史 bug 导致的检测结果与实际类型不符) | ⭐⭐⭐ |
对象类型(Object) | 1. 用{} 定义,存储键值对集合; 2. 点语法访问属性; 3. 堆内存存储,引用访问 | 1. 与原始类型的内存差异(栈 vs 堆); 2. 原始类型的临时包装机制 | ⭐⭐ |
null 的特殊性 | 1. 表示空对象引用,指向 0x0 地址; 2. typeof 返回 object; 3. 布尔转换为 false | 1. 与空对象{} 的区别(内存占用、布尔转换); 2. 历史 bug 的记忆 | ⭐⭐⭐⭐ |
类型初始化规范 | 1. 数字→0;字符串→"";布尔→false;对象→null; 2. 禁止显式赋值 undefined | 1. 空对象{} 在逻辑判断中转为 true 的风险; 2. 不同类型的初始化选择 | ⭐⭐⭐ |
包装类机制 | 原始类型访问属性时临时转为对应对象(如 string→String),访问后销毁 | 原始类型与包装对象的区别(如"a" 是原始值,new String("a") 是对象) | ⭐⭐⭐⭐ |
内存管理原理 | 1. 原始类型存栈内存; 2. 对象存堆内存,变量存引用; 3. null 不占堆内存 | 1. 引用类型的内存地址传递; 2. null 的内存指向特性 | ⭐⭐⭐⭐ |
undefined 与 null 对比 | undefined 是未赋值,null 是主动空对象;前者隐式,后者显式 | 开发中初始化对象变量必须用 nul |
8. Object 和 Null 类型(补充)
1. 数据类型总结
-
基本分类:JavaScript 共包含 8 种数据类型,分为 7 种原始类型(基本数据类型)和 1 种引用类型(复杂数据类型)。
-
具体类型及用途:
类型 核心用途 特殊说明 number
存储整数、浮点数等所有数字 不区分整数与浮点数,统一归为 number
string
存储文本数据(含 0 个或多个字符) 用单引号、双引号或反引号包裹 boolean
存储逻辑真假值 仅 true
(真)和false
(假)两个取值undefined
标记变量 “声明未初始化” 的默认状态 仅有 undefined
一个值,隐式赋值null
标记对象 “为空” 的状态 仅有 null
一个值,需显式赋值object
存储复杂数据集合(键值对形式) 唯一的引用类型,数据存于堆内存 bigint
存储超大整数(超出 number
安全范围)后续进阶学习,基础阶段暂不深入 symbol
生成唯一标识符(避免属性名冲突) 后续进阶学习,基础阶段暂不深入 -
设计目的与关键区别:
-
null
的设计目的:专门用于 对象类型的初始化,当变量预期存储对象但初始值未知时使用(如let product = null;
)。 -
undefined
的设计目的:表示变量 声明后未赋值 的默认状态(如let name;
中name
隐式为undefined
)。 -
核心原则:二者设计语义不同,无需过度纠结细节,重点记住 “对象初始化用
null
,未赋值默认undefined
” 即可。
-
2. Object 类型详解
-
基本使用:作为复杂数据类型,
object
可整合多种原始类型数据,形成键值对结构的复杂数据集合,示例:
// 整合个人信息(包含string、number、boolean类型) let person = {name: "张三",age: 25,isStudent: false };
-
属性访问:通过点语法(对象.属性名)获取对象属性值,示例:
console.log(person.name); // 输出:"张三"(访问name属性) console.log(person.age); // 输出:25(访问age属性)
-
初始化建议:当对象变量初始值未知时,推荐赋值为
null
,而非空对象{}—— 避免空对象在堆内存中占用空间,且防止逻辑判断误判(后续详解),示例:let user = null; // 推荐:后续可赋值为具体用户对象 // let user = {}; // 不推荐:创建空对象,占用堆内存
3. Null 类型详解
-
类型检测特性:使用
typeof检测null时,会返回"object",这是 JavaScript 历史遗留 bug(早期将null定义为 “空对象引用”),需特殊记忆(实际null是原始类型),示例:
console.log(typeof null); // 输出:"object"(历史bug,非实际类型)
-
布尔转换特性:在逻辑判断中,null会转为false,这是其核心特性之一,示例:
if (null) {console.log("执行"); // 不执行(null 转 false) }
-
使用场景:仅用于对象类型的初始化或清空,典型场景包括:
-
异步数据加载前(如请求接口前,
let data = null;
); -
清空对象引用(如不再使用某对象时,
user = null;
)。
-
-
与空对象
{}
的核心区别:对比维度 null
空对象 {}
内存占用 不占用堆内存(指向空地址) 占用堆内存(创建空对象结构) 布尔转换结果 转为 false
转为 true
设计用途 标记 “对象为空” 存储空的键值对集合 初始化推荐度 推荐(对象变量初始值未知时) 不推荐(易造成内存浪费和逻辑误判)
9. 数据类型的转换(梗概介绍)
1. 数据类型的转换定义
-
转换场景:开发中需频繁将一种数据类型转为另一种,常见场景包括:
-
字符串数字(如
"100"
)与数字(如200
)运算; -
文本(如
"订单数量:"
)与数字(如5
)拼接; -
判断逻辑中使用非布尔类型(如
if ("")
)。
-
-
转换必要性:JavaScript 中不同类型数据无法直接运算,需先统一类型(如
true + 10
需先将true
转为数字1
)。 -
例题:字符串转数字类型:
let numStr = "1234"; // 类型为 string(虽内容是数字,仍属字符串) let result = numStr; // 直接赋值,result 仍为 string 类型 // 需显式转为 number 类型才能进行数值运算 let num = Number(numStr); // 转为 number 类型 console.log(num + 100); // 输出:1334(数字运算)
-
转换方式分类:
-
隐式转换:由 JavaScript 引擎自动完成(无需开发者干预);
-
显式转换:开发者主动调用转换方法(如
Number()
、String()
)。
-
2. 数据类型的自动转换(隐式转换)
-
自动转换机制:当运算符或函数需要特定类型数据时,引擎会自动将值转为目标类型,示例:
let isAdmin = true; // boolean 类型 let result2 = 10 + isAdmin; // 引擎自动将 true 转为数字 1 console.log(result2); // 输出:11(10 + 1 = 11)
-
常见布尔值隐式转换规则:
-
true
自动转为数字1
; -
false
自动转为数字0
。
-
-
专业术语:这种由引擎自动完成的转换称为 “隐式转换”(Implicit Conversion),是开发中易忽略但需重点掌握的特性。
3. 数据类型的显示转换(显式转换)
-
转换分类:
转换类型 触发方式 适用场景 隐式转换 引擎自动触发(如运算、判断时) 无需手动干预的简单场景 显式转换 开发者调用转换方法(如 Number()
)需要明确控制转换结果的场景 -
常见转换类型:核心围绕String、Number、Boolean三种类型的相互转换,undefined和null仅需掌握转为Boolean的规则:
-
undefined
转Boolean
:false
; -
null
转Boolean
:false
。
-
-
数据类型转换总结:
-
重点类型:
String
、Number
、Boolean
三者间的转换(开发中最常用); -
特殊说明:
undefined
和null
很少转为其他类型,仅需记住其布尔转换结果为false
。
-
4. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
数据类型分类 | 8 种类型:7 种原始类型(number/string/boolean/undefined/null/symbol/bigint)+ 1 种引用类型(object) | 1. undefined 与 null 的语义区别; 2. null 归为原始类型但 typeof 显式 object | ⭐⭐ |
类型转换概念 | 分隐式(引擎自动)和显式(手动调用方法),开发中需频繁转换以统一运算类型 | 1. 隐式转换的触发场景(如 true + 10 ); 2. 布尔值转数字的规则(true→1 /false→0 ) | ⭐⭐⭐ |
对象初始化规范 | 对象变量初始值未知时,必须赋值为 null ,而非空对象 {} | 1. null 与 {} 的内存差异(空地址 vs 堆内存占用); 2. 二者布尔转换结果不同(false vs true ) | ⭐⭐⭐⭐ |
字符串转数字演示 | 字符串数字(如 "1234" )需显式用 Number() 转为数字类型才能运算 | 1. 带引号的数字本质是 string 类型; 2. 隐式转换可能导致意外结果(如 "10" + 5 = "105" ) | ⭐⭐ |
布尔值转换规则 | 布尔值参与运算时自动转为数字(true→1 /false→0 ),是最常用的隐式转换 | 1. 逻辑判断中布尔转换的结果; 2. undefined /null 转布尔均为 false | ⭐ |
数据类型回顾 | 各类型核心用途:数字存 number 、文本存 string 、逻辑存 boolean 、对象存 object | 1. undefined 是 “未赋值”,null 是 “空对象”; 2. 原始类型与引用类型的本质区别 | ⭐⭐⭐ |
教学难点说明 | 空对象与 null 的底层区别(内存、转换)易造成理解混乱 | 1. 初学者优先掌握 “对象初始化用 null ” 的规范; 2. 底层原理后续逐步深入 |
10. 数据类型转换(String-Number)
一、字符串的转换
概念理解后,接下来讲解字符串类型的转换。首先介绍将其他类型转换为字符串类型的方法。
1. 其他类型转成字符串
字符串类型转换指将其他类型(如数字、布尔值等)转化为字符串类型。例如将数字123
或布尔值true
转化为字符串"123"
或"true"
。常用转换方法包括隐式转换和显式转换两种方式。
1) 隐式转换
-
转换规则:当字符串与其他类型使用加号运算符(+)时,非字符串类型会自动转为字符串,最终结果为字符串拼接。典型应用场景是将目标类型与空字符串("") 相加,简洁实现转换:
let num = 123; let boolValue = true; // 数字转字符串 let numStr = num + ""; console.log(typeof numStr); // 输出:"string",值为"123" // 布尔值转字符串 let boolStr = boolValue + ""; console.log(typeof boolStr); // 输出:"string",值为"true"
-
注意事项:
-
console.log()
函数内部会自动执行字符串转换(无论传入何种类型,最终均以字符串形式打印); -
隐式转换无需调用额外方法,是开发中最常用的字符串转换方式。
-
2) 显式转换
-
转换方法:
-
使用String()函数:直接传入目标值,返回对应的字符串,支持所有原始类型转换,示例:
String(123); // 返回 "123"(数字转字符串) String(true); // 返回 "true"(布尔值转字符串) String(null); // 返回 "null"(null转字符串)
-
使用
toString()
方法:需通过目标变量调用(如num.toString()
),但undefined
和null
无法使用该方法(会报错),详细用法后续面向对象章节讲解。
-
-
开发建议:
-
追求简洁高效时,优先使用隐式转换(如
num + ""
); -
需明确表达 “类型转换” 意图、提升代码可读性时,使用显式转换(如
String(num)
)。
-
二、数字类型的转换
数字类型转换主要讲解将其他类型转为数字类型的方法。
1. 其他类型转成数字类型
数字类型转换包含隐式转换和显式转换两种方式,核心是将非数字类型(如字符串、布尔值)转为number
类型。
1) 隐式转换
-
触发条件:当非数字类型参与非加法的数学运算(如乘法*、除法/、减法-)时,引擎会自动将其转为数字类型后计算。
示例:
// 字符串"8"和"4"参与乘法,自动转为数字8和4 let result = "8" * "4"; console.log(result); // 输出:32(数字类型) console.log(typeof result); // 输出:"number"
-
注意事项:
-
加法运算(+)不会触发数字隐式转换:若加法中存在字符串,会优先触发字符串拼接(如
"8" + 4
返回"84"
,而非12
); -
隐式转换依赖运算场景,实际开发中使用频率较低,多以显式转换为主。
-
2) 显式转换
-
核心转换方法:
-
Number()函数:严格按照 “整体值” 转换,适用于标准数字格式的转换,示例及规则:
Number("123"); // 返回 123(纯数字字符串→数字) Number(" 123 "); // 返回 123(首尾空格会忽略) Number(""); // 返回 0(空字符串→0) Number("123a"); // 返回 NaN(含非数字字符→NaN) Number(true); // 返回 1(布尔值true→1) Number(false); // 返回 0(布尔值false→0) Number(null); // 返回 0(null→0) Number(undefined); // 返回 NaN(undefined→NaN)
-
parseInt()/parseFloat()函数:按 “字符顺序解析”,适用于提取字符串中的数字(后续详解),与Number()的区别示例:
Number("123a"); // 返回 NaN(整体非数字) parseInt("123a"); // 返回 123(解析开头的数字部分)
-
2. 数字类型转换总结
各原始类型转数字的规则如下表,需重点记忆特殊情况:
原始类型 | 转换示例 | 转换结果 | 关键说明 |
---|---|---|---|
undefined | Number(undefined) | NaN | 唯一无法转为有效数字的原始类型 |
null | Number(null) | 0 | 设计上视为 “空的数字占位符” |
boolean | Number(true) /Number(false) | 1 /0 | 布尔值与数字的对应规则 |
string | Number("123") | 123 | 纯数字字符串→对应数字 |
string | Number(" 123 ") | 123 | 首尾空格会自动忽略 |
string | Number("") | 0 | 空字符串→0 |
string | Number("123a") | NaN | 含非数字字符→NaN(非数字) |
三、布尔类型转换
布尔类型转换在开发中应用广泛,常用于逻辑判断场景(如if
条件、逻辑运算)。当使用非布尔类型进行判断时,系统会隐式将其转换为布尔类型;也可通过显式调用Boolean()
函数实现转换。转换规则统一,核心是区分 “空值” 与 “非空值”。
1. 隐式转换
-
触发场景:逻辑运算(如&&、||、!)或条件判断语句(如if、while)中,非布尔值会自动转为布尔类型。转换逻辑:系统先执行 “非布尔→布尔” 的隐式转换,再基于转换结果进行判断或运算。
示例:
let num = 123; // num是数字类型,先隐式转为布尔值true,再执行判断 if (num) { console.log("执行"); // 输出:"执行"(因转换结果为true) }
-
核心转换规则:
-
转为
false
的 “空值”(共 5 种,需牢牢记住):
-
数字
0
(包括0
、-0
); -
空字符串
""
(长度为 0 的字符串); -
undefined
(未初始化的变量值); -
null
(空对象引用); -
NaN
(非数字值)。
-
-
转为
true
的 “非空值”:除上述 5 种空值外,所有值均转为true,例如:-
非 0 数字(如
123
、-45
、3.14
); -
非空字符串(如
"hello"
、"0"
、" "
(空格字符串)); -
对象(如
{}
、[]
,后续对象章节讲解)。
-
-
2. 显式转换
-
实现方式:通过调用
Boolean()
函数,传入目标值即可,转换规则与隐式转换完全一致。
示例:
Boolean(0); // 返回 false(数字0→false) Boolean(""); // 返回 false(空字符串→false) Boolean("0"); // 返回 true(非空字符串→true) Boolean(null); // 返回 false(null→false) Boolean(123); // 返回 true(非0数字→true)
-
易混淆点提醒:
-
空字符串
""
转为false
,但包含空格的字符串" "
转为true
(因后者非空); -
字符串
"0"
转为true
(JavaScript 中仅空字符串视为 “空值”),而部分编程语言(如 PHP)会将"0"
视为false
,需注意区别。
-
3. 布尔类型转换总结
JavaScript 中三类核心类型转换(其他类型→字符串、数字、布尔)中,布尔转换是最关键的一类,直接影响逻辑判断的正确性,需重点掌握:
-
牢记5 种转为
false
的特殊值:0
、""
、undefined
、null
、NaN
; -
所有 “非空值” 均转为
true
,尤其是非空字符串(包括"0"
、" "
)和非 0 数字; -
隐式转换是开发中最常见的形式(如
if
条件判断),显式转换仅用于明确表达转换意图。
11. JavaScript 基础运算符
1. 运算符和运算元
1)运算符
-
基本概念:运算符是用于执行特定运算的符号,例如加号
+
、乘号*
、减号-
、除号/
等,它们定义了对数据的处理方式。 -
语言通用性:几乎所有编程语言都包含运算符(也称为操作符,operators),不同语言的运算符设计高度相似。掌握 JavaScript 运算符后,很容易迁移到其他语言(如 C/C++、Objective-C、Python 等)。
-
学习建议:
-
初次接触时可能觉得运算符种类繁多,但无需刻意死记硬背;
-
日常开发中会频繁使用,通过实际练习实践能自然掌握;
-
高级语言的运算符设计理念相通,理解核心逻辑即可触类旁通。
-
-
分类依据:JavaScript 根据使用场景和功能,将运算符分为多种类型,主要包括:
-
算术运算符(如
+
、-
、*
、/
); -
赋值运算符(如
=
、+=
、-=
); -
关系 / 比较运算符(如
>
、<
、==
、===
); -
逻辑运算符(如
&&
、||
、!
,将在分支语句中详细讲解)。
-
2)运算元
-
定义:运算符所作用的对象称为运算元(也称为参数),是运算的具体数据。
-
示例分析:在表达式5 * 2中:
-
*
是运算符(乘法运算符); -
5
是左运算元(运算符左侧的对象); -
2
是右运算元(运算符右侧的对象)。
-
-
分类标准:根据运算符作用的运算元数量,可分为:
-
一元运算符:仅作用于1 个运算元的运算符,例如负号
-
(如-10
中,-
作用于10
); -
二元运算符:作用于2 个运算元的运算符,例如加法
+
(如2 + 3
中,+
作用于2
和3
); -
三元运算符:作用于3 个运算元的运算符,JavaScript 中唯一的三元运算符是条件运算符(如
条件 ? 值1 : 值2
)。
-
-
常见一元运算符:
-
正号
+
:使用较少,数字默认为正数(如+5
与5
等效); -
负号
-
:常用,用于将数字取反(如-10
表示 “负 10”)。
-
-
特点:
-
一元负号运算符(unary negation)的核心功能是转换数字的正负;
-
运算符的 “元” 数由其作用的运算元数量决定,而非符号本身(例如
-
既可以是一元运算符表示负号,也可以是二元运算符表示减法)。
-
-
特殊说明:
-
条件运算符是 JavaScript 中唯一的三元运算符,理解运算元概念有助于后续学习其语法;
-
区分运算符的 “元” 数,能避免混淆相似符号的不同功能(如
-
在-x
中是一元运算符,在x - y
中是二元运算符)。
-
2. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
运算符基础概念 | 运算符的定义、分类,及与运算元的关系;一元、二元、三元运算符的区分 | 1. 同一符号的不同 “元” 数(如- 作为负号是一元,作为减法是二元); 2. 运算元数量对运算符功能的影响 | ⭐⭐ |
算术运算符 | 加减乘除(+ 、- 、* 、/ )的符号表示和运算规则 | 1. 乘法用* 而非× ,除法用/ 而非÷ ; 2. 运算结果的类型转换(如字符串参与+ 会转为拼接) | ⭐ |
赋值运算符 | 等号= 的赋值逻辑,及变种运算符(+= 、-= 等)的简写规则 | 1. 赋值运算符与数学等号的区别(= 是赋值,非 “等于” 判断); 2. 复合赋值的运算顺序(如x += 5 等效于x = x + 5 ) | ⭐⭐ |
自增自减运算符 | ++ (自增)和-- (自减)对变量值的增减操作 | 1. 前置(++i )与后置(i++ )的执行顺序差异(先增减再运算 vs 先运算再增减); 2. 仅能作用于变量(不能用于常量,如5++ 报错) | ⭐⭐⭐ |
运算符优先级 | 多运算符表达式的计算顺序规则(如先乘除后加减) | 1. 与小学数学优先级的异同(如逻辑运算符优先级低于比较运算符); 2. 括号对优先级的改变((a + b) * c 优先计算括号内) | ⭐⭐ |
比较运算符 | 比较运算(> 、< 、== 等)的结果为布尔类型(true /false ) | 1. == (宽松相等)与=== (严格相等)的区别(是否检查类型); 2. 特殊值比较(如NaN === NaN 为false ) | ⭐⭐⭐⭐ |
三元运算符 | 条件运算符条件 ? 值1 : 值2 的逻辑(条件为真返回值 1,否则返回值 2) | 1. 三个运算元的关系(条件表达式、真值结果、假值结果); 2. 与if-else 的功能等效性及使用场景差异 | ⭐⭐⭐ |
跨语言通用性 | JavaScript 运算符与其他语言(Java/C++ 等)的相似性和差异 | 1. 符号差异(如** 表示幂运算仅在 JavaScript 等部分语言支持); 2. 运算规则的共通性(如算术运算符逻辑基本一致) | ⭐⭐ |
12. JavaScript 常见的运算符
1. JavaScript 中运算符
1)算数运算符的使用
-
基本概念:算术运算符用于执行数学计算,语法和使用逻辑与数学中的运算规则一致,核心作用是对数字(或可转为数字的类型)进行计算。JavaScript 中常用算术运算符包括:加法
+
、减法-
、乘法*
、除法/
、取余%
、求幂**
。 -
各运算符详细说明与示例:
-
加法运算(+) 功能:根据运算元类型,分为 “数字加法” 和 “字符串拼接” 两种场景:
-
数字加法:当两个运算元均为数字(或可转为数字的类型)时,执行数值相加;
-
字符串拼接:当任意一个运算元为字符串时,执行字符串拼接。 示例:
// 数字加法 console.log(3 + 5); // 输出:8(纯数字相加) console.log(3 + Number("5")); // 输出:8(字符串转数字后相加) // 字符串拼接 console.log("中" + "国"); // 输出:"中国"(两个字符串拼接) console.log("年龄:" + 25); // 输出:"年龄:25"(数字与字符串拼接)
-
-
减法运算(-) 功能:仅执行数值减法,若运算元为非数字类型,会先隐式转为数字后计算(无法转为数字则返回
NaN
)。 示例:console.log(10 - 4); // 输出:6(纯数字减法) console.log(10 - "4"); // 输出:6(字符串"4"转数字后减法) console.log(10 - "abc"); // 输出:NaN("abc"无法转数字)
-
乘法运算(*) 功能:执行数值乘法,非数字类型会先隐式转为数字(无法转数字则返回
NaN
)。 例题:乘法运算 代码示例:// 直接数值乘法 console.log(6 * 7); // 输出:42 // 变量存储数值后运算(结果与直接计算一致) let a = 6; let b = 7; console.log(a * b); // 输出:42
-
除法运算(/) 功能:执行数值除法,返回精确的浮点结果(非整数),非数字类型先隐式转数字(无法转则返回
NaN
)。 例题:除法运算 代码示例:// 20除以8,得到精确浮点结果 console.log(20 / 8); // 输出:2.5(非整数结果,保留小数) console.log(10 / 2); // 输出:5(整数结果,仍以数字类型返回)
-
取余运算(%) 功能:返回 “被除数除以除数后的余数”(结果符号与被除数一致),非数字类型先隐式转数字。 例题:取余运算 代码示例:
// 运算原理:20 ÷ 8 = 2 余 4,因此取余结果为4 console.log(20 % 8); // 输出:4 console.log(15 % 4); // 输出:3(15 ÷ 4 = 3 余 3) console.log(-15 % 4); // 输出:-3(结果符号与被除数-15一致)
应用场景:虽日常使用频率不高,但在特定场景不可或缺,例如:
-
判断数字奇偶性(
num % 2 === 0
表示偶数); -
循环中控制周期(如每 5 次执行一次操作)。
-
-
求幂运算()** 功能:计算 “底数的指数次方”(等价于数学中的
底数^指数
),ES7(ES2016)新增语法,比传统Math.pow()
方法更简洁。 例题:求幂运算 代码示例:// 语法对比:** 运算符 vs Math.pow() 方法 console.log(2 ** 3); // 输出:8(2的3次方,ES7语法) console.log(Math.pow(2, 3)); // 输出:8(传统方法,与**结果一致) console.log(5 ** 2); // 输出:25(5的2次方,即25)
数学表示:
a ** b
等价于数学中的aᵇ
。
-
2)取余 % 和求幂 ** 的补充说明
-
取余运算符(%)
-
符号含义:
%
仅表示 “取余”,与 “百分数” 无关(切勿混淆); -
核心功能:返回 “被除数 ÷ 除数” 后的余数,计算逻辑遵循数学中的余数规则;
-
示例:
10 % 3 = 1
(10 ÷ 3 = 3 余 1)、7 % 7 = 0
(整除时余数为 0)。
-
-
求幂运算符()**
-
符号含义:
**
是 ES7(2016 年发布)新增的求幂符号,专门用于 “幂运算”; -
核心功能:计算 “左运算元(底数)的右运算元(指数)次方”;
-
版本说明:ES 版本命名规则为 “ES 年份”,如 ES6=ES2015(2015 年发布)、ES7=ES2016(2016 年发布),
**
仅在支持 ES7 及以上的环境中可用(现代浏览器和 Node.js 均支持); -
示例:
3 ** 4 = 81
(3 的 4 次方)、10 ** 0 = 1
(任何数的 0 次方为 1)。
-
2. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
算术运算符 | 包含加 (+)、减 (-)、乘 (*)、除 (/),执行基本数学运算;+ 同时支持字符串拼接 | 1. 加号 (+) 的双重功能(数字加法 vs 字符串拼接); 2. 除法 (/) 返回浮点结果(非整数截断) | ⭐ |
取余运算符 | 符号 %,返回除法后的余数;结果符号与被除数一致 | 1. 取余与除法的区别(如 20%8=4 vs 20/8=2.5); 2. 负数取余的结果符号(如 - 20%8=-4) | ⭐⭐ |
幂运算符 | 符号 **(ES7 新增),计算底数的指数次方;等价于 Math.pow (底数,指数) | 1. ** 与 Math.pow () 的功能等价性; 2. ES 版本支持范围(需 ES7 及以上) | ⭐⭐ |
运算符优先级 | 算术运算符优先级与数学一致(先乘除、取余、求幂,后加减);括号可改变优先级 | 1. 多运算符表达式的计算顺序(如 3+4*2=11,非 14); 2. 一元正号 (+) 与加法 (+) 的区别(优先级:一元 > 二元) | ⭐⭐ |
ES 版本特性 | ES 版本命名规则(ES6=ES2015,ES7=ES2016);(求幂) 是 ES7 新增语法** | 1. 不同 ES 版本的特性差异; 2. 兼容性判断(老旧环境不支持 **) |
13. 赋值和链式赋值运算符
1. 赋值运算符
1)赋值运算符的定义
-
定义:赋值运算符的符号为 等号(=),核心功能是将 “等号右侧的值或表达式结果” 赋给 “等号左侧的变量”,完成变量的初始化或值更新。
-
本质属性:赋值运算符不仅是 “赋值操作”,更是 JavaScript 中的标准运算符(与算术运算符、比较运算符并列),执行后会返回 “被赋予的值”(这是链式赋值的基础)。
示例:
// 初始化变量:将10赋给变量num let num = 10; // 更新变量:将num+5的结果(15)赋给num num = num + 5; // 赋值运算符返回被赋予的值:console.log会打印赋值结果15 console.log(num = 20); // 输出:20
2)链式赋值
-
概念:链式赋值允许通过连续的等号(=),将同一个值或表达式结果一次性赋给多个变量,语法形式为
变量1 = 变量2 = 变量3 = 表达式
。 例题:链式赋值计算顺序 以let a = b = c = 2 + 2
为例,执行逻辑如下:-
计算顺序:链式赋值严格遵循 从右向左 的执行顺序,先计算最右侧的表达式(
2 + 2
结果为 4); -
赋值流程:将表达式结果依次向左赋值 —— 先赋给最右侧变量
c
(c = 4
),再将c
的值赋给b
(b = c
,即b = 4
),最后将b
的值赋给a
(a = b
,即a = 4
); -
最终结果:
a
、b
、c
的值均为 4。
-
-
链式赋值的特点:
-
简洁性:用一行代码替代多行重复赋值,减少代码量,例如:
// 链式赋值(一行完成3个变量赋值) let x = y = z = 0; // 等价于逐个赋值(3行代码) let x = 0; let y = 0; let z = 0;
-
-
链式赋值的缺点:
-
可读性差:连续赋值会隐藏变量间的关联逻辑,其他开发者需追溯到最右侧表达式才能明确赋值内容,尤其变量数量多时,理解成本升高;
-
潜在风险:若链式赋值中包含未声明的变量,会意外创建全局变量(非严格模式下),例如:
let a = 1; a = b = 2; // b未声明,非严格模式下会成为全局变量,污染全局作用域
-
推荐做法:若多个变量需赋相同值,优先选择 逐个声明并赋值,虽代码量增加,但可读性和可维护性更强。
-
3)链式调用的扩展
-
概念:链式调用与链式赋值逻辑相似,指通过 “点语法连续调用对象的方法”,让多个方法执行语句合并为一行,常见于处理对象操作(如数组方法、DOM 操作、第三方库 API)。
-
核心原理:若对象的方法执行后返回 “对象本身(this)”,则可继续调用该对象的其他方法,形成链式结构。
示例(后续学习中会接触):
// 假设arr是数组,filter、map方法执行后均返回新数组,可链式调用 const result = arr.filter(item => item > 0).map(item => item * 2); // 等价于分步调用(2行代码) const filteredArr = arr.filter(item => item > 0); const result = filteredArr.map(item => item * 2);
-
应用场景:链式调用在 jQuery、Vue、React 等库 / 框架中极为常见,后续学习对象和方法时会深入讲解,此处仅需了解 “链式” 的核心思想即可。
2. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
赋值运算符 | 符号为= ,将右侧值 / 表达式结果赋给左侧变量;本身是运算符,执行后返回被赋值 | 1. 赋值运算符不是 “数学等号”(x = x + 5 是更新值,非等式成立); 2. 理解 “返回被赋值” 的特性(链式赋值的基础) | 低 |
链式赋值 | 语法 变量1 = 变量2 = 表达式 ,从右向左执行,一次性赋相同值 | 1. 执行顺序(必须从右向左,而非从左向右); 2. 与运算符优先级的关联(赋值运算符优先级低,需注意括号影响) | 中 |
链式赋值的优劣 | 优点是简洁(一行完成多变量赋值);缺点是可读性差、有全局变量风险 | 1. 开发规范:推荐逐个赋值而非链式赋值; 2. 非严格模式下未声明变量的风险(如a = b = 2 中 b 成全局变量) | 中 |
链式调用扩展 | 基于 “方法返回对象本身” 实现连续调用,常见于库 / 框架 API | 1. 与链式赋值的逻辑共性(均为 “连续操作”); 2. 后续对象方法学习的铺垫 | 低 |
14. 赋值运算符
-
运算符本质:
=
并非特殊语言结构,而是标准运算符,称为赋值(assignments)运算符,与+
、*
等算术运算符的语法地位一致。 -
执行机制:赋值语句x = value的核心逻辑是 “先将value的值写入变量x,再返回x的值”(返回值特性是链式赋值的基础),示例:
let x; console.log(x = 5); // 输出:5(赋值后返回x的值)
-
链式赋值:
-
语法示例:
let a = b = c = 2 + 2
; -
计算顺序:严格从右向左执行 —— 先计算最右侧表达式
2 + 2
(结果为 4),再依次将 4 赋给c
、b
、a
; -
变量共享:最终
a
、b
、c
均指向同一个值(4); -
代码规范:虽语法合法,但链式赋值会降低代码可读性(需追溯到最右侧才能明确值来源),实际开发中不推荐使用。
-
15. 原地修改
1. 概念与基本使用
-
定义:原地修改(英文:modify in place)指 “对变量进行运算后,将运算结果重新存储回原变量” 的操作,核心是 “复用原变量存储新结果”,避免创建新变量。
-
典型场景:需更新变量值时(如计数器累加、数值放大),示例:
let num = 10; // 原地修改:对num加5后,将结果存回num num = num + 5; console.log(num); // 输出:15
-
执行原理:赋值语句中,右侧表达式(如
num + 5
)的优先级高于赋值运算符=
,因此会先计算num + 5
的结果(15),再通过=
将结果写回num
。 -
语法糖:为简化 “运算 + 赋值” 的重复写法,JavaScript 提供
+=
、*=
等简写形式(语法糖),替代完整表达式,减少代码冗余。
2. 运算符简写形式
-
支持范围:所有算术运算符(
+
、-
、*
、/
、%
、**
)和位运算符(后续讲解),均有对应的原地修改简写形式。 -
常见简写及等价关系:
简写形式 | 运算符类型 | 简写表达式 | 等价的完整表达式 | 功能说明 |
---|---|---|---|---|
+= | 加等于 | num += 10 | num = num + 10 | 变量值加 10 后存回原变量 |
-= | 减等于 | num -= 10 | num = num - 10 | 变量值减 10 后存回原变量 |
*= | 乘等于 | num *= 10 | num = num * 10 | 变量值乘 10 后存回原变量 |
/= | 除等于 | num /= 10 | num = num / 10 | 变量值除以 10 后存回原变量 |
%= | 取余等于 | num %= 10 | num = num % 10 | 变量值对 10 取余后存回原变量 |
**= | 幂等于 | num **= 2 | num = num ** 2 | 变量值的 2 次方结果存回原变量 |
-
开发建议:
-
日常开发中优先使用简写形式(如
num += 5
替代num = num + 5
),减少重复变量名的书写,提升代码简洁性; -
位运算符(如
&=
、|=
)的简写形式在前端开发中极少使用,无需刻意记忆,后续需用时查阅 MDN 文档 即可。
-
3. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
赋值运算符 | = 是运算符,执行 “写值 + 返回值”;链式赋值从右向左执行,不推荐使用 | 1. 区分 “赋值运算符” 与 “数学等号”(x = x + 5 是更新值,非等式); 2. 链式赋值的执行顺序(避免误认为从左向右) | ⭐ |
原地修改(Modify in Place) | 运算后将结果存回原变量;依赖 “先算表达式,再赋值” 的执行顺序 | 1. 右侧表达式的优先级(如 num += 3 * 2 等价于 num = num + (3*2) ); 2. “原地” 的含义(复用原变量,不创建新变量) | ⭐⭐ |
算术运算符简写 | 所有算术运算符支持简写(+= 、*= 等),等价于完整表达式 | 1. 简写与完整写法的等价性(如 num **= 2 等价于 num = num ** 2 ); 2. 位运算符简写的低使用率(无需重点记忆) | ⭐⭐ |
语法糖概念 | 简写形式是语法糖,仅简化代码表达,无功能新增 | 1. 理解 “语法糖” 的本质(不改变逻辑,仅提升开发效率); 2. 简写形式的兼容性(现代环境均支持,无需担心兼容问题) | ⭐ |
16. 自增、自减
1. 自增自减的概念
-
定义:自增(
++
)和自减(--
)是专门用于 “变量数值加 1” 或 “变量数值减 1” 的特殊运算符,是原地修改的 “特例”(针对最常见的 ±1 操作)。 -
运算符说明:
-
++
(自增运算符):使变量值 增加 1; -
--
(自减运算符):使变量值 减少 1。
-
-
本质:是对 “
变量 = 变量 + 1
”“变量 = 变量 - 1
” 的进一步简化,语法在多数编程语言中通用(如 Java、C++)。
2. 自增自减的常用场景
自增自减是开发中高频使用的运算符,典型场景包括:
-
音乐 / 视频播放器的 “上一曲 / 下一曲” 功能(控制播放列表索引);
-
循环结构中的计数器(如
for
循环的索引递增); -
数据统计中的数量计数(如商品加入购物车的次数统计)。
案例说明:播放列表功能实现 假设播放列表用数组 playList = ["歌曲A", "歌曲B", "歌曲C"]
存储,currentIndex
表示当前播放歌曲的索引(从 0 开始):
-
下一曲操作:需将索引加 1,可写为
currentIndex += 1
或currentIndex++
; -
上一曲操作:需将索引减 1,可写为
currentIndex -= 1
或currentIndex--
。
3. 自增运算符的使用
实现 “变量加 1” 有三种方式,自增运算符是最简洁的形式:
实现方式 | 代码示例 | 特点 |
---|---|---|
常规写法 | currentIndex = currentIndex + 1 | 最直观,但代码冗余 |
复合赋值写法 | currentIndex += 1 | 简化冗余,但仍需写 “+=1” |
自增运算符写法 | currentIndex++ 或 ++currentIndex | 最简洁,专为 “加 1” 设计 |
优势:自增运算符使代码更简洁,且是跨语言通用语法,降低切换语言的学习成本。
4. 自减运算符的使用
实现 “变量减 1” 同样有三种方式,逻辑与自增一致:
实现方式 | 代码示例 | 特点 |
---|---|---|
常规写法 | currentIndex = currentIndex - 1 | 直观但冗余 |
复合赋值写法 | currentIndex -= 1 | 简化冗余 |
自减运算符写法 | currentIndex-- 或 --currentIndex | 最简洁,专为 “减 1” 设计 |
效果验证:
let num = 5; num++; // 自增:num变为6 num--; // 自减:num恢复为5 console.log(num); // 输出:5
5. 自增自减的注意事项
-
使用限制:自增 / 自减运算符仅能作用于变量,不能直接作用于数值字面量(如5、10.5)或表达式,否则会报错。
错误示例:
5++; // 报错:Uncaught ReferenceError: Invalid left-hand side expression in postfix operation (a + b)++; // 报错:无法对表达式结果执行自增
-
设计原理:数值字面量是 “常量”(值不可修改),而自增 / 自减需要将新结果存回原 “容器”,只有变量才能承担这一角色(变量可存储变化后的值)。
-
语言通用性:多数高级编程语言(如 Java、C++、Python 虽不支持
++
/--
,但有类似+=1
语法)均支持类似逻辑,语法设计高度相似。
6. ++ 和 -- 的位置
1. 自增和自减的位置举例
自增 / 自减运算符根据与变量的位置关系,分为 前置形式(运算符在变量前,如++num
)和 后置形式(运算符在变量后,如num++
),二者的核心区别在于 “返回值” 和 “运算时机”。
(1)独立使用时的等效性
当自增 / 自减作为 独立表达式(不与其他运算、赋值混合)时,前置和后置形式的 最终变量值变化完全相同,仅返回值不同(但独立使用时无需关注返回值)。 示例:
let currentIndex = 5; currentIndex++; // 后置自增:currentIndex变为6 // 等价于 let currentIndex = 5; ++currentIndex; // 前置自增:currentIndex同样变为6
(2)复合表达式中的区别
当自增 / 自减与其他运算(如赋值、打印)混合时,差异会体现:
-
后置形式(num++):先使用变量的原值参与运算,再对变量执行自增;
-
前置形式(++num):先对变量执行自增,再使用新值参与运算。
示例对比:
// 后置形式:先使用原值,再自增 let a = 5; let b = a++; // 步骤1:b = a(b=5);步骤2:a自增(a=6) console.log(a, b); // 输出:6 5 // 前置形式:先自增,再使用新值 let c = 5; let d = ++c; // 步骤1:c自增(c=6);步骤2:d = c(d=6) console.log(c, d); // 输出:6 6
(3)实际开发建议
为避免逻辑混淆和代码可读性下降,强烈推荐将自增 / 自减拆分为独立步骤,而非混合在复杂表达式中。 不推荐写法(可读性差):
let result = (num++) * 2; // 需额外思考运算顺序
推荐写法(拆分步骤,清晰直观):
num++; // 第一步:先自增 let result = num * 2; // 第二步:再参与运算
2. 运算符 ++ 和 -- 的位置
(1)术语定义
-
后置形式(postfix form):运算符位于变量右侧,语法
变量++
或变量--
; -
前置形式(prefix form):运算符位于变量左侧,语法
++变量
或--变量
。
(2)核心区别:返回值差异
形式 | 运算顺序 | 返回值 | 示例(初始 num=5) |
---|---|---|---|
后置(num++) | 1. 返回 num 原值;2. num 自增 1 | 自增前的原值 | let res = num++; → res=5,num=6 |
前置(++num) | 1. num 自增 1;2. 返回 num 新值 | 自增后的新值 | let res = ++num++; → res=6,num=6 |
(3)使用场景
-
需 立即使用自增 / 自减结果 时,用前置形式(如
let res = ++num;
); -
需 保留原值参与其他操作,后续再更新变量时,用后置形式(如
let res = num++;
)。
(4)记忆要点
-
口诀:“前置先算后用,后置先用后算”;
-
关键原则:独立使用时无差别,复合表达式时必须关注位置,优先考虑代码可读性而非语法简洁性。
7. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
原地修改 | 运算后将结果存回原变量;复合赋值运算符(+= /*= 等)是简化写法 | 1. 复合运算符与完整表达式的等价性(如num *= 2 ≡ num = num * 2 ); 2. 运算优先级(右侧表达式先算,再赋值) | ⭐⭐ |
自增 / 自减运算符 | ++ (加 1)/-- (减 1),是原地修改的特例;仅作用于变量 | 1. 禁止作用于数值字面量(如5++ 报错); 2. 与复合赋值的区别(num++ ≡ num += 1 ,但更简洁) | ⭐⭐ |
播放列表索引管理 | 用currentIndex++ /currentIndex-- 控制索引,实现上下曲切换 | 1. 数组索引从 0 开始(而非 1); 2. 索引越界问题(需后续处理,如最后一曲后切第一曲) | ⭐⭐ |
++/-- 的位置差异 | 前置 “先算后用”,返回新值;后置 “先用后算”,返回原值 | 1. 复合表达式中的结果差异(如res = num++ vs res = ++num ); 2. 独立使用与复合使用的区别 | ⭐⭐⭐ |
运算符使用规范 | 推荐单独使用自增 / 自减,避免混合在复杂表达式中 | 1. 代码可读性优先(拆分步骤比简写更重要); 2. 面试高频考点:前置与后置的返回值差异 | ⭐⭐⭐⭐ |
变量操作限制 | 自增 / 自减仅能作用于变量,不能作用于常量或表达式 | 1. 错误案例分析(如(a+b)-- 报错); 2. 设计原理(变量可存储变化后的值) |
17. 运算符的优先级
在 JavaScript 表达式中,当存在多个运算符时,并非按 “从左到右” 顺序执行,而是遵循运算符优先级规则(类似数学中的 “先乘除后加减”)—— 优先级高的运算符先执行,优先级低的后执行。
例如表达式 result = 2 + 3 * 5
包含三种运算符:赋值运算符(=
)、加法运算符(+
)、乘法运算符(*
)。因优先级:*
> +
> =
,执行顺序为:
-
先计算
3 * 5 = 15
(乘法优先级最高); -
再计算
2 + 15 = 17
(加法次之); -
最后将
17
赋值给result
(赋值优先级最低)。
若表达式包含自增运算符(如 ++
),其优先级更高(前置 ++
优先级高于乘法),例如 result = 2 + 3 * ++number
(假设 number=5
):
-
先执行
++number
(number
变为6
,前置自增优先级最高); -
再计算
3 * 6 = 18
(乘法次之); -
接着计算
2 + 18 = 20
(加法再次之); -
最后赋值
result=20
(赋值最低)。
⚠️ 注意:自增 / 自减运算符不能直接作用于数字字面量(如 ++5
会报错),必须通过变量实现(如 let number=5; ++number
)。
1. 例题:运算符优先级示例
以 let result = 2 + 3 * ++number
(初始 number=5
)为例,完整计算步骤如下:
-
确定优先级顺序:前置
++
(优先级 16) > 乘法*
(优先级 14) > 加法+
(优先级 13) > 赋值=
(优先级 3); -
执行前置自增:
++number
→number
从5
变为6
(返回值6
); -
执行乘法运算:
3 * 6 = 18
; -
执行加法运算:
2 + 18 = 20
; -
执行赋值操作:
result = 20
; -
最终结果:
result=20
,number=6
。
若需改变默认优先级,可使用分组运算符(()
)(优先级最高,19),例如 let result = (2 + 3) * ++number
:
-
先执行括号内
2 + 3 = 5
,再计算5 * 6 = 30
,最终result=30
。
2. 运算符优先级的汇总表
以下是开发中常用的运算符优先级(优先级数字越大,执行顺序越靠前;完整表格可参考 MDN 文档):
优先级 | 运算符类型 | 运算符示例 | 说明 | ||
---|---|---|---|---|---|
19 | 分组运算符 | () | 强制改变运算顺序,优先级最高 | ||
18 | 成员访问运算符 | . | 如 obj.property ,访问对象属性 | ||
16 | 自增 / 自减运算符(前置) | ++变量 、--变量 | 先自增 / 减,再参与运算 | ||
14 | 乘法 / 除法 / 取余运算符 | * 、/ 、% | 算术运算符,优先级高于加法 / 减法 | ||
13 | 加法 / 减法运算符 | + 、- | 算术运算符,优先级低于乘法 / 除法 | ||
11 | 比较运算符 | > 、< 、=== | 如 a > b ,返回布尔值 | ||
6 | 逻辑与运算符 | && | 逻辑运算,优先级低于比较运算符 | ||
5 | 逻辑或运算符 | ` | ` | 逻辑运算,优先级低于逻辑与 | |
3 | 赋值运算符 | = 、+= 、*= | 所有运算完成后才执行,优先级极低 | ||
2 | 逗号运算符 | , | 优先级最低,用于分隔表达式 |
核心注意事项
-
括号优先:分组运算符
()
优先级最高,可通过括号明确控制运算顺序,避免因优先级混淆导致错误(推荐优先使用括号提升可读性); -
自增 / 减的特殊性:前置
++
/--
优先级(16)高于乘法(14),后置++
/--
优先级(15)低于乘法,需区分位置差异; -
赋值运算符最后执行:无论表达式多复杂,赋值操作(
=
、+=
等)始终在所有运算完成后执行; -
开发建议:日常开发中无需死记所有优先级,遵循 “数学常识”(先乘除后加减)即可;若对运算顺序存疑,直接用
()
明确顺序,或拆分为多个简单表达式(优先保证可读性)。
18. ==
和 ===
的区别
在 JavaScript 中,==
(普通相等运算符)和 ===
(严格相等运算符)均用于判断两个值是否 “相等”,但核心差异在于是否进行隐式类型转换—— 这是开发中避免逻辑错误的关键知识点。
1. 普通相等性检查(==
)的问题:隐式类型转换
==
被称为 “宽容相等”,当比较的两个值类型不同时,会先自动执行隐式类型转换(默认转为 Number
类型,特殊值除外),再比较转换后的值是否相等。这种自动转换虽看似灵活,却常导致意外结果。
(1)核心转换规则与特殊案例
比较场景 | 隐式转换逻辑 | 示例 | 结果 | 原因分析 |
---|---|---|---|---|
字符串 vs 数字 | 字符串转为 Number | "" == 0 | true | Number("") = 0 ,转换后 0 == 0 |
布尔值 vs 数字 | 布尔值转为 Number (true→1 ,false→0 ) | false == 0 | true | Number(false) = 0 ,转换后 0 == 0 |
null vs 数字 | null 特殊处理,不转为 Number (即使 Number(null)=0 ) | null == 0 | false | null 仅与 undefined 用 == 比较为 true |
undefined vs 数字 | undefined 转为 Number 为 NaN (NaN 与任何值不相等) | undefined == 0 | false | Number(undefined) = NaN ,NaN != 0 |
null vs undefined | 二者为 “特殊匹配”,无需转换 | null == undefined | true | 语言设计特例,仅这一种跨类型匹配为 true |
(2)转换机制验证:用 Number()
显式模拟
==
的隐式转换本质是调用 Number()
函数(除 null
/undefined
特例),可通过显式转换验证结果:
// 1. 空字符串转 Number console.log(Number("")); // 输出:0 → 因此 "" == 0 为 true // 2. 布尔值转 Number console.log(Number(false)); // 输出:0 → 因此 false == 0 为 true // 3. null 转 Number(但比较时特殊处理) console.log(Number(null)); // 输出:0 → 但 null == 0 为 false(特例) // 4. undefined 转 Number console.log(Number(undefined)); // 输出:NaN → 因此 undefined == 任何值均为 false
(3)==
的风险
隐式转换可能导致违背直觉的结果,例如:
console.log("1" == 1); // true("1" 转 Number 为 1) console.log(true == 1); // true(true 转 Number 为 1) console.log("true" == true); // false("true" 转 Number 为 NaN,NaN != 1)
这些结果需额外记忆规则,增加了代码调试难度。
2. 严格相等运算符(===
):无隐式转换,更安全
===
被称为 “严格相等”,其比较逻辑完全不进行隐式类型转换,判断标准是 “类型相同 + 值相同”—— 只要类型不同,直接返回 false
;类型相同时,再比较值是否相等。
(1)核心比较规则
-
第一步:检查两个值的类型是否相同(如
string
vsnumber
、null
vsundefined
),类型不同则返回false
; -
第二步:若类型相同,再比较值是否相等(如
123 === 123
、"abc" === "abc"
)。
(2)示例对比:==
vs ===
比较表达式 | == 结果 | === 结果 | 原因分析(=== ) |
---|---|---|---|
"" == 0 | true | false | 类型不同(string vs number ),直接返回 false |
false == 0 | true | false | 类型不同(boolean vs number ),直接返回 false |
null == undefined | true | false | 类型不同(null vs undefined ),直接返回 false |
"123" === 123 | true | false | 类型不同(string vs number ),直接返回 false |
5 === 5 | true | true | 类型相同(number )且值相同,返回 true |
(3)对应的 “不相等” 运算符
-
!=
:普通不相等,先隐式转换再判断(==
的相反逻辑); -
!==
:严格不相等,不转换类型,类型不同或值不同均返回true
(===
的相反逻辑)。
示例:
console.log("" != 0); // false(先转换为 0 == 0,再取反) console.log("" !== 0); // true(类型不同,直接判断不相等)
3. 开发建议:优先使用 ===
-
避免意外错误:
===
无需处理隐式转换的特殊规则,结果更可预测(如"" === 0
明确为false
,不会因转换导致逻辑混乱); -
代码意图更清晰:使用
===
能明确表达 “既比较类型,也比较值” 的意图,其他开发者无需猜测是否存在隐式转换; -
特殊值处理:
null
和undefined
仅需用===
区分(null === undefined
为false
),避免==
的特例干扰。
禁用 ==
的场景:除了 “判断变量是否为 null
或 undefined
”(obj == null
等价于 obj === null || obj === undefined
),其他场景均推荐用 ===
。
4. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
普通相等运算符(== ) | 类型不同时先隐式转 Number (特殊值除外),再比较值;存在诸多特例 | 1. null == undefined 为 true 的特例; 2. "" == 0 、false == 0 等反直觉结果 | ⭐⭐⭐ |
严格相等运算符(=== ) | 不进行隐式转换,“类型相同 + 值相同” 才返回 true ;开发推荐使用 | 1. 与 == 的核心差异(是否转换类型); 2. null === undefined 为 false (类型不同) | ⭐⭐ |
类型转换机制 | == 依赖 Number() 转换(除 null /undefined );=== 无转换 | 1. Number(null)=0 但 null == 0 为 false 的特例; 2. undefined 转 Number 为 NaN | ⭐⭐⭐⭐ |
开发实践建议 | 禁止使用 == (除 obj == null 场景),统一用 === 确保逻辑安全 | 1. 如何通过 === 避免隐式转换错误; 2. !== 与 != 的区别 | ⭐⭐ |
19. 代码执行方式和代码块儿理解
一、分支语句
分支语句是 JavaScript 中控制程序 “执行路径” 的核心语法,通过条件判断决定 “哪些代码执行、哪些代码不执行”,核心包括 if
系列语句、三元运算符、switch
语句等。在学习具体分支语法前,需先理解程序的执行顺序和代码块的概念。
1. 程序的执行顺序
程序的执行顺序决定了代码的运行逻辑,JavaScript 支持三种核心执行方式,其中 “分支执行” 是分支语句的基础。
1)默认执行顺序:顺序执行
程序默认按照 “从上至下、逐行解析” 的顺序执行,代码书写顺序直接决定运行顺序,不存在条件判断或重复执行。 示例:
// 第1行:声明变量number1并赋值10 let number1 = 10; // 第2行:声明变量number2并赋值20(第1行执行完才执行) let number2 = 20; // 第3行:计算求和并赋值(第2行执行完才执行) let result = number1 + number2; // 第4行:打印结果(第3行执行完才执行) console.log(result); // 输出:30
上述代码严格按 “1→2→3→4” 的顺序执行,无任何分支或跳转。
2)程序的三种执行方式
除了默认的顺序执行,程序还支持 “分支执行” 和 “循环执行”,三者共同构成流程控制的核心:
执行方式 | 核心逻辑 | 适用场景 | 关键语法 |
---|---|---|---|
顺序执行 | 从上至下逐行执行,无判断、无重复 | 简单的线性逻辑(如变量声明、直接计算) | 无特殊语法,默认执行方式 |
分支执行 | 通过条件判断(true/false)决定执行路径,“选一条路走” | 需要根据不同条件执行不同代码(如 “登录成功则跳转,失败则提示”) | if 、if-else 、switch 、三元运算符 |
循环执行 | 通过条件判断重复执行代码块,“重复走一条路直到条件不满足” | 需要重复执行某段逻辑(如 “遍历数组的所有元素”) | for 、while 、do-while |
3)执行顺序总结
-
顺序执行是 “基础”,分支和循环执行是 “对顺序执行的干预”;
-
分支语句的核心作用是 “打破顺序执行”,根据条件动态选择执行代码;
-
后续学习的
if
、switch
等语法,本质都是 “分支执行” 的具体实现。
2. 代码块的理解
代码块是程序结构的基本单元,用于将多行代码 “打包” 为一个独立整体,通常与流程控制语句(如 if
、while
)配合使用。
1)代码块的定义与语法
代码块通过 一对花括号 { }
包裹多行代码形成,语法格式:
{// 代码块内部的代码(可包含变量声明、表达式、函数调用等)let a = 1;let b = 2;console.log(a + b); // 输出:3 }
-
代码块内部的变量、函数等,其作用域会受代码块限制(后续 “作用域” 章节详解);
-
代码块本身不改变执行顺序(内部代码仍逐行执行),但可被流程控制语句 “整体控制”(如
if
条件满足时才执行整个代码块)。
2)代码块与 “对象字面量” 的区别
初学者易混淆代码块与对象字面量(如 let obj = { name: "why" }
),二者虽都用 { }
,但本质完全不同:
对比维度 | 代码块({ } ) | 对象字面量({ key: value } ) |
---|---|---|
核心作用 | 打包多行代码,作为流程控制的 “执行单元” | 定义对象,存储键值对形式的复杂数据 |
语法特征 | 内部是 “执行语句”(如 let a=1; 、console.log() ) | 内部是 “键值对”(如 name: "why" ,键和值用冒号分隔) |
使用场景 | 配合 if 、while 等语句(如 if(条件){ 代码块 } ) | 存储数据(如用户信息、商品信息) |
示例 | { let x=5; console.log(x); } | let user = { name: "张三", age: 25 } |
3)代码块的核心特征
-
作用域隔离:代码块内部声明的变量(如let、const声明的变量),默认仅在代码块内部可访问(外部无法直接使用),示例:
{let a = 10; // 代码块内部声明的变量console.log(a); // 输出:10(内部可访问) } console.log(a); // 报错:Uncaught ReferenceError: a is not defined(外部不可访问)
-
与流程控制配合:代码块常作为if、while等语句的 “执行体”,例如:
let score = 85; if (score >= 80) {// 条件满足时,执行整个代码块console.log("成绩优秀");console.log("获得A等级"); }
若没有代码块,
if
仅能控制 “紧随其后的第一行代码”,代码块则实现了 “多代码的整体控制”。
二、分支语句的预告
基于上述 “执行顺序” 和 “代码块” 的基础,后续将详细讲解具体分支语法:
-
if
语句:单条件分支(“满足条件则执行,不满足则跳过”); -
if-else
语句:双条件分支(“满足条件走 A 路,不满足走 B 路”); -
if-else if-else
语句:多条件分支(“多个条件依次判断,选第一个满足的路径”); -
三元运算符:简洁的双条件分支(“条件?满足时的值:不满足时的值”);
-
switch
语句:基于 “严格相等” 的多值匹配分支(“匹配到某个值则执行对应代码”)。
20. ECMAScript 标准文档介绍
ECMAScript 标准是 JavaScript 语言的 “官方说明书”,定义了语言的语法、数据类型、执行机制等核心规则,所有 JavaScript 引擎(如 V8、SpiderMonkey)均基于此标准实现。
1. 标准核心信息
-
标准定义:ECMA-262 是 ECMAScript 语言的官方标准文档(以示例中 “ECMAScript 2020” 为例,对应第 11 版标准),明确规范了语言的所有核心特性。
-
版本历史:第一版发布于 1997 年 6 月,后续通过版本迭代完善功能,关键版本里程碑包括:
-
第三版(1999 年):新增正则表达式、异常处理(
try-catch
)等核心特性; -
第五版(2009 年):增加严格模式(
use strict
)、JSON 支持、数组新增方法(如forEach
)等重要功能。
-
-
国际标准地位:已被国际标准化组织(ISO/IEC)采纳为国际标准(ISO/IEC 16262),确保语言在全球范围内的一致性。
2. 文档内容概述
标准文档的核心内容围绕 “语言如何工作” 展开,主要包括:
-
定义 ECMAScript 的数据类型和值(如
string
、number
、null
、undefined
等); -
规范抽象操作(如类型转换的底层逻辑、相等性比较的步骤);
-
详细说明执行上下文和代码执行机制(如变量提升、作用域链);
-
规定源代码的词法语法(如标识符规则、运算符优先级)。
3. 访问注意事项
-
访问限制:官方文档托管于
ecma-international.org
,国内可能无法直接访问,需通过科学上网工具稳定获取完整内容。 -
文档特点:文档体积较大(包含大量技术细节和规范描述),加载和检索需要一定时间,建议提前明确查询目标(如 “
==
运算符的比较规则”)。
4. ==
操作符比较规则(标准视角)
-
主要规则:当比较的两个值类型不同时,大多数情况下会先将操作数转换为数字(Number 类型),再比较转换后的值(如
"" == 0
因Number("")=0
返回true
)。 -
特殊情况:存在少数不进行数字转换的例外,例如
null == undefined
直接返回true
(语言设计特例,不触发类型转换)。 -
使用建议:因
==
的转换规则复杂且易产生反直觉结果,标准文档虽定义其逻辑,但实际开发中推荐优先使用严格相等运算符===
(不进行类型转换,结果更可预测)。
21. 验证 “内容不一致” 的方法
在学习或开发中,若发现书籍、MDN 文档与实际代码运行结果不符,需通过 “权威溯源” 验证,确保理解符合标准。
1. 文档验证的核心逻辑
-
不一致处理原则:当不同资料的描述冲突时,需追溯 “最权威的参考源”,而非依赖单一资料(如某本教材可能存在笔误,而标准文档是最终依据)。
-
分领域权威参考:
-
CSS 领域:优先查询 W3C 官方文档(W3C 是 CSS 标准的制定机构);
-
JavaScript 领域:优先查询 ECMAScript 标准文档,其次是 MDN 文档(基于标准整理,且更新及时)。
-
2. JavaScript 学习的权威资源排序
按 “权威性从高到低” 排序,推荐以下资源用于验证和学习:
-
ECMAScript 标准文档:语言设计的 “源头”,所有特性的最终依据;
-
MDN 文档(developer.mozilla.org):社区维护的权威教程,基于标准整理,包含代码示例和浏览器兼容性说明;
-
JavaScript.info:在线交互式教程,内容严谨且贴近标准,部分章节对应实体书籍;
-
《JavaScript 高级程序设计》:经典书籍,适合系统学习,但需注意版本(建议选择最新版,匹配当前 ECMAScript 标准)。
3. 验证流程(三步确认法)
-
查标准文档:明确某特性的 “官方定义”(如 “代码块的作用域规则”);
-
看实际实现:在浏览器控制台或 Node.js 中运行代码,观察实际结果(如
{ let a=1; } console.log(a)
是否报错); -
做开发验证:将特性融入简单 demo(如 “代码块配合
if
语句使用”),确认实际开发场景中的表现是否与标准一致。
22. 代码块基础
代码块是 JavaScript 中组织代码的基本单元,用于将多行执行语句打包为一个独立整体,是流程控制语句的核心载体。
1. 代码块的定义与必要性
-
基本概念:通过一对花括号
{ }
包裹多行执行代码形成的集合,示例:
{let name = "why"; // 变量声明let message = "my name is " + name; // 表达式计算console.log(message); // 函数调用(输出:my name is why) }
-
开发必要性:单行代码通常无法完成完整功能(如 “登录验证后跳转页面” 需要多步操作),代码块可将相关逻辑 “聚合”,提升可读性和可维护性。
2. 代码块与流程控制的关系
代码块本身不改变执行顺序(内部代码仍逐行执行),但需通过流程控制关键字(如 if
、for
)控制 “是否执行” 或 “执行次数”,主要控制类型包括:
-
分支语句:通过条件判断控制代码块的执行(如
if
满足条件则执行代码块,switch
匹配值则执行对应代码块); -
循环语句:通过条件判断控制代码块的重复执行(如
for
循环让代码块执行指定次数,while
循环让代码块执行到条件不满足为止)。
3. 代码块的核心特征
-
作用域隔离:代码块内部用
let
/const
声明的变量,默认仅在代码块内部可访问(外部无法直接引用,避免变量污染); -
与对象字面量的区别:代码块内部是 “执行语句”(如
let a=1;
),而对象字面量(如{ name: "why" }
)内部是 “键值对”(用于存储数据),二者语法相似但功能完全不同。
23. 分支语句的实现
分支语句是 “根据条件选择执行路径” 的语法,本质是对现实生活中 “判断逻辑” 的代码抽象,所有主流编程语言均支持此类结构。
1. 生活中的条件判断(代码映射)
现实场景中的 “判断逻辑” 可直接映射为代码中的分支语句,示例:
生活场景 | 核心判断逻辑 | 代码映射(分支语句) | ||
---|---|---|---|---|
小明考 100 分去游乐场 | 是否满足 “分数 = 100” | if (score === 100) { console.log("去游乐场"); } | ||
网吧准入机制 | 同时满足 “年龄≥18”“有身份证”“有资金” | if (age >= 18 && hasID && hasMoney) { 允许进入; } | ||
登录系统验证 | 满足 “账号密码正确” 或 “二维码扫描成功” | `if (pwdCorrect | qrScanned) {跳转主页;} else { 提示错误;}` |
2. 什么是分支结构
-
本质特征:根据一个或多个条件的 “真 / 假(true/false)”,决定代码的执行方向 —— 满足条件则执行 A 代码块,不满足则执行 B 代码块(或跳过)。
-
别称说明:又称 “判断结构”“选择结构”,不同编程语言命名不同(如 C 语言中称 “选择语句”),但逻辑完全一致。
-
语言通用性:C/C++、Objective-C、JavaScript 等主流语言均支持分支结构,语法细节可能差异(如 JavaScript 的
if
条件无需括号包裹),但核心逻辑相同。
3. 分支结构的类型(以 if
系列为例)
if
系列是 JavaScript 中最常用的分支结构,根据 “条件数量” 分为单分支和多分支两种:
(1)单分支结构(if
语句)
-
基本形式:仅包含一个
if
条件判断,无其他分支,语法:
if (条件表达式) {// 条件为true时执行的代码块(条件为false则跳过) }
-
典型场景:只需处理 “条件成立” 的情况,无需处理 “不成立” 的逻辑(如 “年龄≥18 则显示成年提示,不成年则无操作”)。
-
示例:
let age = 20; if (age >= 18) {console.log("已成年,可独立办理业务"); // 条件为true,执行此代码块 }
(2)多分支结构(if-else if-else
语句)
-
基本形式:通过
if(初始条件)
else if(后续条件)
else(兜底)形成 “阶梯式判断”,语法:
if (条件1) {// 条件1为true时执行,执行后退出整个判断链 } else if (条件2) {// 条件1为false、条件2为true时执行,执行后退出 } else {// 所有条件均为false时执行(可选,用于兜底) }
-
执行逻辑:按 “条件 1→条件 2→…→else” 的顺序依次判断,执行第一个满足条件的代码块后,立即退出整个分支结构(后续条件不再判断)。
-
必含要素:必须包含初始的
if
语句;else if
可包含 0 个或多个;else
可包含 0 个或 1 个(最多 1 个,用于 “所有条件不满足” 的兜底)。 -
示例:根据成绩判断等级:
let score = 85; if (score >= 90) {console.log("等级A"); } else if (score >= 80) {console.log("等级B"); // 条件1为false,条件2为true,执行此代码块 } else if (score >= 60) {console.log("等级C"); } else {console.log("等级D"); }
4. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 | ||
---|---|---|---|---|---|
ECMAScript 文档查询 | 需科学上网访问官方文档,用于验证 JS 特性的标准定义;文档体积大,加载需时间 | 1. 国内访问限制的解决方案; 2. 文档检索技巧(明确查询目标) | ⭐⭐ | ||
JS 学习资源排序 | 权威优先级:ECMA 标准 > MDN > JavaScript.info > 《高级程序设计》 | 1. 不同资源的适用场景(如标准查规则,MDN 查示例); 2. 资源版本匹配(避免旧内容) | ⭐ | ||
== 比较规则 | 多数情况转数字比较,存在 null == undefined 等特例;推荐用 === | 1. 转换规则的复杂性(需结合标准理解); 2. 与 === 的核心差异 | ⭐⭐⭐ | ||
分支结构分类 | if 单分支(仅处理条件成立)、if-else if-else 多分支(阶梯判断) | 1. 多分支的执行逻辑(先满足先执行,执行后退出); 2. else 的兜底作用 | ⭐⭐ | ||
生活场景抽象 | 现实判断逻辑(如登录验证)映射为分支语句;代码是现实的抽象表达 | 1. 如何将 “多条件判断”(如网吧准入)转为代码; 2. 条件表达式的编写(如 && /` | ` 的使用) | ⭐ | |
分支语句通用性 | 所有主流语言均支持,语法细节差异但逻辑一致(如 C/JS 的 if 语法) | 1. 跨语言语法对比(如 C 需括号包裹条件,JS 可选); 2. 逻辑一致性(判断顺序、退出机制) | ⭐ |
24. 分支语句
分支语句的核心是 “根据条件选择性执行代码”,其中 单分支结构(if
语句) 是最基础的形式,仅在条件满足时执行代码块,不满足则跳过。
1. 单分支结构
(1)基本语法与执行逻辑
-
语法格式:
if (条件表达式) {// 代码块:条件表达式结果为 true 时执行,为 false 时跳过 }
-
if
:关键字,标记分支的开始; -
条件表达式
:放在小括号()
内,最终需返回布尔值(true
/false
),或可隐式转为布尔值的值; -
代码块
:用大括号{}
包裹的多行代码,是if
语句的 “执行体”—— 条件满足时,代码块内的代码会逐行执行;条件不满足时,代码块会被完全跳过。
-
-
执行逻辑:
-
先计算
()
内的 “条件表达式” 结果; -
将结果隐式转换为布尔值(
true
/false
); -
若为
true
,执行{}
内的代码块;若为false
,直接跳过代码块,执行if
语句之后的代码。
-
(2)例题 1:考试成绩判断
题目需求:定义考试分数 score
,若分数大于 90 分,打印 “去游乐场玩”;否则不执行任何操作。
-
题目解析:
-
变量定义:需用
var
/let
声明score
并赋值(如let score = 85
); -
条件判断:用
score > 90
作为条件表达式(结果为true
表示分数达标); -
执行逻辑:若
score = 99
,条件99 > 90
为true
,执行打印;若score = 85
,条件85 > 90
为false
,跳过打印。 -
开发扩展:实际项目中,“去游乐场” 可能是复杂操作(如跳转页面、调用接口),可封装为函数(如
goToAmusementPark()
),在代码块内调用。
-
-
代码实现:
// 1. 定义分数变量 let score = 99; // 若改为85,代码块不执行 // 2. 单分支判断 if (score > 90) {console.log("去游乐场玩"); // 条件满足时执行:输出“去游乐场玩”// 开发扩展:调用函数(示例)// goToAmusementPark(); } // 条件不满足时,直接执行此处代码(示例) console.log("判断结束");
(3)例题 2:苹果购买折扣
题目需求:苹果单价 5 元 / 斤,购买重量为 weight
斤,计算总价 totalPrice
;若购买重量超过 5 斤,总价立减 8 元,最终打印 “购买重量:X 斤,最终总价:X 元”。
-
题目解析:
-
变量定义:需声明
price
(单价,固定为 5)、weight
(购买重量,如 3 斤)、totalPrice
(总价,初始为price * weight
); -
计算逻辑:先算基础总价(
totalPrice = price * weight
),再判断是否满足折扣条件; -
条件判断:用
weight > 5
作为条件(超过 5 斤触发折扣); -
折扣处理:满足条件时,用
totalPrice -= 8
(等价于totalPrice = totalPrice - 8
)计算最终价; -
输出方式:用
console.log()
传入多个参数(如console.log("购买重量:", weight, "斤,最终总价:", totalPrice, "元")
)。
-
-
易错点:
-
忘记先算基础总价,直接对未定义的
totalPrice
操作(如if(weight>5) { totalPrice -=8 }
,会报错undefined
); -
条件边界处理错误(如将
weight > 5
误写为weight >=5
,导致 5 斤也触发折扣,不符合需求); -
折扣计算用直接赋值(如
totalPrice = 8
),而非totalPrice -=8
(逻辑错误,会将总价改为 8 元)。
-
-
代码实现:
// 1. 定义基础变量 const price = 5; // 单价固定,用const声明 let weight = 6; // 购买重量(示例:6斤,超过5斤) let totalPrice = price * weight; // 先算基础总价:5*6=30 // 2. 单分支判断:超过5斤立减8元 if (weight > 5) {totalPrice -= 8; // 折扣后总价:30-8=22 } // 3. 打印结果 console.log("购买重量:", weight, "斤,最终总价:", totalPrice, "元"); // 输出:购买重量:6 斤,最终总价:22 元
2. if
语句的细节补充
(1)代码块省略规则
if
语句的代码块 {}
并非永远必须 —— 当代码块内只有一行代码时,可以省略 {}
,但需注意可读性和潜在风险。
-
语法示例:
let age = 19; // 单行代码,可省略{}(不推荐初学者使用) if (age >= 18) console.log("已成年"); // 等价于完整写法(推荐) if (age >= 18) {console.log("已成年"); }
-
注意事项:
-
代码位置:省略
{}
后,单行代码可写在if
同一行,也可换行,但换行可能导致逻辑混淆(如后续代码误被当作分支内代码); -
初学者建议:不建议省略
{}
,即使只有一行代码 —— 完整的{}
能明确代码块范围,避免因后续修改(如新增代码)导致逻辑错误(例如误将第二行代码纳入分支); -
开发规范:团队开发中,通常要求保留
{}
,以保证代码一致性和可读性。
-
-
苹果折扣案例的省略写法(不推荐):
let weight = 7; let totalPrice = 5 * weight; if (weight > 5) totalPrice -= 8; // 单行代码,省略{} console.log("最终总价:", totalPrice);
(2)条件判断的隐式转换
if
语句的 “条件表达式” 无需显式返回布尔值 ——JavaScript 会自动将表达式结果隐式转换为布尔类型(Boolean
),再判断执行与否。
-
核心规则:
-
假值(falsy):6 种值会被转为
false
,分别是:0
、空字符串""
、null
、undefined
、NaN
、false
本身; -
真值(truthy):除假值外的所有值,都会被转为
true
,例如:非 0 数字(123
、-45
)、非空字符串("abc"
、"0"
)、对象({}
、[]
)、函数等。
-
-
数值判断示例:
// 1. 假值案例:条件表达式结果为0,转为false,代码块不执行 let num = 0; if (num) {console.log("num是真值"); // 不执行 } // 2. 真值案例:条件表达式结果为"hello"(非空字符串),转为true,代码块执行 let str = "hello"; if (str) {console.log("str是真值"); // 输出:str是真值 }
-
边界情况处理(播放列表案例): 需求:播放列表
playList
有 3 首歌(索引0
、1
、2
),currentIndex
表示当前播放索引;若currentIndex
超过最大索引(playList.length - 1 = 2
),则重置为0
(循环播放)。 代码实现:const playList = ["歌曲1", "歌曲2", "歌曲3"]; let currentIndex = 3; // 超过最大索引2 // 条件:currentIndex > 最大索引(2),转为true,执行重置 if (currentIndex > playList.length - 1) {currentIndex = 0; // 重置为0 } console.log("当前播放索引:", currentIndex); // 输出:当前播放索引:0
-
开发建议: 处理类似 “循环逻辑”“边界值判断” 时,必须明确假值 / 真值的转换规则 —— 例如不能用
if (currentIndex)
判断索引是否有效(若currentIndex = 0
,会被转为false
,误判为无效),而应直接比较数值(if (currentIndex < 0 || currentIndex >= playList.length)
)。
3. 知识小结
知识点 | 核心内容 | 考试重点 / 易混淆点 | 难度系数 |
---|---|---|---|
分支结构基础概念 | 基于条件选择性执行代码,与 “顺序执行” 的核心区别是 “有判断、有选择” | 1. 分支结构与顺序结构的本质差异(是否依赖条件); 2. 单分支的 “仅满足时执行” 逻辑 | ⭐⭐ |
if 语句语法 | 标准格式 if(条件表达式){代码块} ;单行代码可省略 {} ,但不推荐 | 1. 代码块省略规则(仅限单行,初学者需保留 {} ); 2. 条件表达式的位置(必须在 () 内) | ⭐⭐⭐ |
条件表达式隐式转换 | 假值(6 种)转 false ,其余转 true ;需区分 “空字符串” 与 “非空字符串” 等 | 1. 6 种假值的准确记忆(尤其是 0 与 "0" 的区别:0 是假值,"0" 是真值); 2. 边界值判断时避免依赖隐式转换(如索引 0 不能用 if(索引) 判断) | ⭐⭐⭐⭐ |
单分支结构案例 | 成绩判断(>90 分奖励)、苹果折扣(>5 斤减 8 元)、播放列表索引重置 | 1. 苹果折扣案例的 “先算基础价,再算折扣” 逻辑; 2. 播放列表案例的 “最大索引计算”(length-1 ) | ⭐⭐⭐ |
代码规范建议 | 变量命名语义化(如 score 表分数,weight 表重量);保留 {} 增强可读性 | 1. 变量命名的语义化要求(避免用 a 、b 等无意义名称); 2. 团队开发中 {} 的保留规范 | ⭐⭐ |
关键字特性 | if 是保留字,具有特殊语法含义,不能作为变量 / 函数名 | 1. 保留字与普通标识符的区别(如 let if = 1 会报错); 2. 关键字的语法解析优先级 |