前端入门学习-JavaScript 数组操作、函数基础与运算符实战
前端入门学习笔记(Day07):JavaScript 数组操作、函数基础与运算符实战
引入:
在前六天的前端学习中,我们已掌握 HTML 结构搭建、CSS 布局美化,以及 JavaScript 的变量声明、数据类型(Day06)、简单 DOM 交互(Day05)等基础能力。随着学习深入,前端开发需处理更复杂的数据(如列表、集合)和逻辑(如排序、条件计算),而 JavaScript 的复合数据类型(数组、对象) 与运算符体系正是解决这些问题的核心工具。
本文聚焦 “数组的全方位操作”“函数基础定义” 和 “运算符的深化应用” 三大模块,既是对数据类型知识的拓展,也为后续学习循环控制、复杂交互奠定基础。本文将逐一解析这些知识点,结合对比(如与 C 语言数组的差异)和实战案例,帮你全面掌握 JS 中数据处理与逻辑运算的核心技巧。
一、JavaScript 复合数据类型:数组(Array)全方位解析
数组是前端开发中最常用的 “数据集合容器”,用于存储列表类数据(如商品列表、用户信息)。Day07 代码首先对比了 JS 数组与 C 语言数组的差异,再深入讲解数组的定义、特殊用法(栈 / 队列)和排序操作,是本节的核心重点。
1.1 JS 数组与 C 语言数组的核心差异
作为弱类型语言,JavaScript 的数组与 C 语言(强类型)数组在设计上有本质区别,这也是初学者容易混淆的点,具体差异如下:
|
对比维度 |
C 语言数组 |
JavaScript 数组 |
|
数据类型兼容性 |
仅能存储相同类型数据(如 int []、char []) |
支持存储不同类型数据(如同时存字符串、数字、布尔值) |
|
越界访问后果 |
直接报错,可能导致程序崩溃 |
不报错,返回undefined(未定义) |
|
长度灵活性 |
声明时需固定长度,后续不可动态修改 |
长度可动态变化(添加 / 删除元素时自动调整) |
|
定义语法 |
需指定类型,如int arr[5] = {1,2,3}; |
无需指定类型,多种定义方式 |
代码示例:JS 数组的灵活定义与多类型存储
// 方式1:通过new Array()构造函数定义,支持多类型数据
var arr = new Array("abc", 88, true, false, null);
console.log(arr); // 输出:["abc", 88, true, false, null]
console.log(arr[0]); // 输出:"abc"(通过下标访问,与C语言一致,下标从0开始)
console.log(arr[10]); // 输出:undefined(越界访问,不报错)
// 方式2:通过“字面量语法”定义(更简洁,前端开发推荐用法)
var arr1 = ["a88", 78, 88.6]; // 同时存储字符串、整数、浮点数
console.log(arr1); // 输出:["a88", 78, 88.6]
1.2 JS 数组的特殊用法:模拟栈(Stack)与队列(Queue)
在算法与数据结构中,“栈” 和 “队列” 是两种基础数据结构,而 JS 数组通过内置方法,可轻松模拟这两种结构的核心功能,无需额外定义类,这也是 Day07 代码的亮点之一。
(1)模拟栈:先进后出(LIFO)
栈的核心规则是 “最后加入的元素最先取出”(如叠盘子,最后放的先拿),JS 数组通过push()(入栈)和pop()(出栈)方法实现:
- push(element):将元素添加到数组末尾(入栈);
- pop():删除并返回数组最后一个元素(出栈)。
代码实战:用数组模拟栈操作
var stack = []; // 初始化空数组,作为栈容器
// 1. 元素入栈:依次添加“孙悟空”“猪八戒”“唐僧”
stack.push("孙悟空");
stack.push("猪八戒");
stack.push("唐僧");
console.log("入栈后栈结构:", stack); // 输出:["孙悟空", "猪八戒", "唐僧"]
// 2. 元素出栈:依次取出最后一个元素
console.log("第一次出栈:", stack.pop()); // 输出:"唐僧"(最后入栈,最先出栈)
console.log("第二次出栈:", stack.pop()); // 输出:"猪八戒"
console.log("第三次出栈:", stack.pop()); // 输出:"孙悟空"
console.log("出栈后栈结构:", stack); // 输出:[](栈空)
(2)模拟队列:先进先出(FIFO)
队列的核心规则是 “最先加入的元素最先取出”(如排队买票,先到先得),JS 数组通过push()(入队)和shift()(出队)方法实现:
- push(element):将元素添加到数组末尾(入队);
- shift():删除并返回数组第一个元素(出队)。
代码实战:用数组模拟队列操作
var queue = []; // 初始化空数组,作为队列容器
// 1. 元素入队:依次添加“aa”“bb”“cc”
queue.push("aa");
queue.push("bb");
queue.push("cc");
console.log("入队后队列结构:", queue); // 输出:["aa", "bb", "cc"]
// 2. 元素出队:依次取出第一个元素
console.log("第一次出队:", queue.shift()); // 输出:"aa"(最先入队,最先出队)
console.log("第二次出队:", queue.shift()); // 输出:"bb"
console.log("第三次出队:", queue.shift()); // 输出:"cc"
console.log("出队后队列结构:", queue); // 输出:[](队列空)
补充说明:Day07 代码中还提到unshift()方法(向数组开头添加元素),若用unshift()入队、shift()出队,会变成 “后进先出” 的逆队列,实际开发中较少用,推荐优先使用push()+shift()模拟标准队列。
1.3 JS 数组排序:从默认排序到自定义排序
数组排序是前端高频需求(如商品价格排序、列表按时间排序),Day07 代码详细演示了 “字符数组排序”“数字数组排序” 的差异,以及如何通过自定义函数实现按数字大小排序。
(1)默认排序:按字符编码逐位排序
JS 数组的sort()方法默认按 “Unicode 字符编码” 排序,而非数学逻辑排序,这会导致数字数组排序出现 “不符合直觉” 的结果:
// 案例1:字符数组排序(符合预期,按字母顺序)
var strArr = ["asdf", "fe", "am", "add"];
console.log("字符数组排序前:", strArr); // 输出:["asdf", "fe", "am", "add"]
strArr.sort();
console.log("字符数组排序后:", strArr); // 输出:["add", "am", "asdf", "fe"](按字母a→f顺序)
// 案例2:数字数组默认排序(不符合预期,按字符编码排序)
var numArr = [11, 123, 84, 141, 56, 67, 444];
console.log("数字数组默认排序前:", numArr); // 输出:[11, 123, 84, 141, 56, 67, 444]
numArr.sort();
console.log("数字数组默认排序后:", numArr); // 输出:[11, 123, 141, 444, 56, 67, 84](错误!)
原因解析:sort()默认将数组元素转为字符串后比较,如 “123” 的第一个字符 “1” 小于 “56” 的第一个字符 “5”,因此 “123” 排在 “56” 前面。
(2)自定义排序:按数字大小排序
要实现数字数组的 “数学逻辑排序”,需给sort()方法传入一个 “比较函数”,通过返回值控制排序规则:
- 比较函数接收两个参数a(前一个元素)和b(后一个元素);
- 返回a - b:按升序排序(从小到大);
- 返回b - a:按降序排序(从大到小)。
代码实战:数字数组自定义排序
var numArr = [11, 123, 84, 141, 56, 67, 444];
console.log("数字数组自定义排序前:", numArr); // 输出:[11, 123, 84, 141, 56, 67, 444]
// 1. 升序排序(a - b)
numArr.sort(function(a, b) {
return a - b;
});
console.log("数字数组升序排序后:", numArr); // 输出:[11, 56, 67, 84, 123, 141, 444](正确)
// 2. 降序排序(b - a)
numArr.sort(function(a, b) {
return b - a;
});
console.log("数字数组降序排序后:", numArr); // 输出:[444, 141, 123, 84, 67, 56, 11](正确)
二、JavaScript 函数基础:函数的定义与核心作用
函数是 “封装可复用代码块” 的核心工具,Day07 代码通过function myTest(){}演示了函数的基础定义。结合前序 Day05 的 “事件绑定”(如onclick触发函数),本节将补充函数的核心作用与基础语法,为后续学习函数参数、返回值铺垫。
2.1 函数的核心作用:代码复用与逻辑封装
在前端开发中,函数的核心价值体现在两点:
- 代码复用:避免重复编写相同逻辑(如多次使用的 “数据验证”“格式转换” 逻辑);
- 逻辑拆分:将复杂功能拆分为多个小函数(如 “表单提交” 拆分为 “验证表单”“发送请求”“显示结果” 三个函数),提升代码可读性和维护性。
2.2 函数的基础定义语法
JS 函数的基础定义方式为 “函数声明式”,语法结构如下:
// 语法:function 函数名(参数列表) { 函数体(可复用的代码) }
function 函数名(参数1, 参数2, ...) {
// 函数体:具体的逻辑代码
console.log("这是一个可复用的函数");
// 后续可通过return返回结果(Day07暂未涉及)
}
// 示例:定义一个“打印数组内容”的复用函数
function printArray(arr) {
console.log("数组内容:", arr);
console.log("数组长度:", arr.length);
}
// 调用函数:通过“函数名(参数)”执行函数
var myArr = [1, 2, 3];
printArray(myArr); // 输出:数组内容:[1,2,3] + 数组长度:3
var anotherArr = ["a", "b"];
printArray(anotherArr); // 输出:数组内容:["a","b"] + 数组长度:2
关联前序知识:Day05 中 “鼠标悬停切换图片” 的onmouseover = function(){},本质是 “匿名函数”(无函数名的函数),后续会学习匿名函数与回调函数的应用。
三、JavaScript 运算符深化:从赋值到三目运算符的实战
Day06 已学习 JS 的基础数据类型,而运算符是 “操作数据、实现逻辑判断” 的工具。Day07 第二个代码文件聚焦 “赋值运算符”“算术运算符”“比较运算符”“逻辑运算符” 和 “三目运算符”,结合数组操作和变量计算,深化运算符的实际应用。
3.1 赋值运算符:基础赋值与数组元素修改
赋值运算符的核心是=,用于将右侧的值赋给左侧的变量或数组元素,是数据存储的基础操作。Day07 代码通过 “修改数组元素” 演示了赋值运算符的灵活应用:
// 1. 基础赋值:给变量赋值
var num = 10; // 将10赋给变量num
// 2. 数组元素赋值:通过下标修改数组元素(结合Day07数组知识点)
var arr = [1, 2, 3, 4, 5];
arr[0] = arr[1]; // 将数组第2个元素(值为2)赋给第1个元素(原 value 为1)
console.log("修改后数组:", arr); // 输出:[2, 2, 3, 4, 5]
3.2 算术运算符:自增自减的核心差异
算术运算符包括+(加)、-(减)、*(乘)、/(除),以及特殊的 “自增(++)”“自减(--)”。Day07 代码重点演示了自增运算符的 “前缀” 与 “后缀” 差异,这是前端面试高频考点:
|
自增方式 |
执行顺序 |
代码示例 |
结果分析 |
|
前缀自增(++a) |
先将变量值 + 1,再使用新值 |
var a=10; var b=++a; |
a=11,b=11(a 先 + 1,再赋给 b) |
|
后缀自增(a++) |
先使用变量当前值,再将变量值 + 1 |
var a=10; var b=a++; |
a=11,b=10(先将 a 的当前值赋给 b,再 + 1) |
代码实战:自增运算符的差异对比
var i = 10;
var j = 10;
// 前缀自增:++i
var b = ++i;
console.log("前缀自增后b的值:", b); // 输出:11(i先+1变为11,再赋给b)
console.log("前缀自增后i的值:", i); // 输出:11
// 后缀自增:j++
var c = j++;
console.log("后缀自增后c的值:", c); // 输出:10(先将j的当前值10赋给c,再+1)
console.log("后缀自增后j的值:", j); // 输出:11
3.3 比较运算符与逻辑运算符:条件判断的基石
比较运算符用于判断 “值的关系”,逻辑运算符用于 “组合多个条件”,二者结合是 Day04 条件语句(if-else)的核心判断依据。Day07 代码重点强调了 “==与===的差异”,这是初学者容易踩坑的点。
(1)比较运算符:==(宽松相等)vs ===(严格相等)
- ==:宽松相等,会先进行 “隐式类型转换”,再比较值是否相等;
- ===:严格相等,不进行类型转换,需同时满足 “值相等” 和 “数据类型相等” 才返回true。
代码实战:宽松相等与严格相等的差异
// 宽松相等(==):先将num2转为数字5,再比较值
console.log(num1 == num2); // 输出:true(值相等,类型不同但被转换)
// 严格相等(===):不转换类型,数字5 vs 字符串"5",类型不同
console.log(num1 === num2); // 输出:false(类型不同,直接返回false)
// 其他常见比较
console.log(0 == false); // 输出:true(0被转为false)
console.log(0 === false); // 输出:false(数字vs布尔,类型不同)
console.log(null == undefined); // 输出:true(特殊规则,二者宽松相等)
console.log(null === undefined); // 输出:false(类型不同:null vs undefined)
开发建议:优先使用===,避免隐式类型转换导致的意外错误(如"" == 0返回true,逻辑上不符合预期)。
(2)逻辑运算符
逻辑运算符用于将多个 “布尔值条件” 组合成复杂判断,是实现多规则校验(如表单验证、权限判断)的关键,Day07 代码明确了三种核心逻辑运算符的规则:
|
逻辑运算符 |
名称 |
运算规则 |
应用场景 |
|
&& |
逻辑与 |
两个操作数同时为 true,结果才为 true;只要有一个为 false,结果即为 false |
需满足 “所有条件” 才执行(如 “年满 18 且已实名认证”) |
|
|| |
逻辑或 |
两个操作数只要有一个为true,结果就为true;操作数全为false,结果才为false |
满足”所有条件“中的一个就可以执行 |
|
! |
逻辑非 |
对单个操作数取反:true 变 false,false 变 true |
否定某个条件(如 “未勾选同意协议”) |
关键特性:短路求值
逻辑运算符存在 “短路求值” 特性,即当第一个操作数已能确定最终结果时,会跳过第二个操作数的计算,提升效率:
- &&短路:若第一个操作数为 false,直接返回 false,不计算第二个操作数;
- ||短路:若第一个操作数为 true,直接返回 true,不计算第二个操作数。
3.4 三目运算符:简化条件判断的 “语法糖”
三目运算符(又称条件运算符)是if-else语句的简化形式,适用于 “二选一” 的简单判断场景,Day07 代码明确其语法为:
条件表达式 ? 表达式1 : 表达式2
- 执行逻辑:先判断 “条件表达式” 的结果;
- 若结果为true,执行并返回 “表达式 1” 的结果;
- 若结果为false,执行并返回 “表达式 2” 的结果。
实战 1:基础使用(直接执行语句)
实战 2:结合变量赋值(更常用场景)
实战 3:嵌套使用(谨慎场景,复杂逻辑推荐用 if-else)
三目运算符支持嵌套,但嵌套层级过多会降低可读性,建议最多嵌套 1-2 层:
console.log("详细等级:", detailGrade); // 输出:详细等级:C(中等)
使用建议:
- 简单二选一逻辑(如变量赋值、简短语句执行)用三目运算符,代码更简洁;
- 复杂逻辑(如多条件判断、需执行多句代码)用if-else,可读性更高。
四、总结:Day07 核心知识点与前序知识衔接
Day07 围绕 “JavaScript 复合数据类型”“函数基础”“运算符深化” 三大模块,完成了从 “基础数据处理” 到 “复杂逻辑实现” 的过渡,关键知识点与前序学习的衔接的如下:
|
Day07 核心知识点 |
实际应用价值 |
|
数组多类型存储、栈 / 队列模拟 |
处理列表数据(商品列表、用户列表) |
|
数组自定义排序 |
实现商品价格排序、列表筛选功能 |
|
函数基础定义 |
封装复用逻辑(表单验证、数据格式化) |
|
严格相等(===)、逻辑运算符 |
精准判断(表单验证、权限控制) |
|
三目运算符 |
简化变量赋值、简短逻辑执行 |
通过 Day07 的学习,我们掌握了前端开发中 “数据存储(数组)”“逻辑封装(函数)”“条件计算(运算符)” 的核心工具。后续学习中,这些知识点将与 “循环控制”“DOM 进阶操作” 结合,实现更复杂的交互功能(如动态渲染列表、表单提交验证)。建议通过实战练习(如用数组 + 运算符实现 “购物车总价计算”)巩固知识点,逐步提升代码应用能力。
更多推荐
所有评论(0)