Python Day32 JavaScript 数组与对象核心知识点整理
一、JavaScript 数组
1. 数组的定义方式
数组有两种主要定义方式,分别是字面量定义和构造方法定义:
字面量定义
语法:let 数组名 = [];
(空数组)或let 数组名 = [元素1, 元素2, ...];
(含初始元素)
示例:let arr = []; // 空数组 let arrWithVals = [10, 'a', true]; // 包含初始元素的数组
构造方法定义(new Array ())
语法及作用:new Array()
:创建空数组new Array(n)
:创建长度为n
且元素均为undefined
的数组(n
为正整数)new Array(值1, 值2, ...)
:创建包含指定元素的数组
示例:
let arr1 = new Array(5); // 长度为5的数组,元素均为undefined let arr2 = new Array(1, 2, 3); // 数组为 [1, 2, 3]
2. 数组的基本操作
包括添加、修改、删除、查询数据及获取长度:
添加数据
push(...vals)
:向数组尾部添加 0~n 个元素
示例:arr.push(10, 20);
(尾部添加 10 和 20)unshift(...vals)
:向数组头部添加 0~n 个元素
示例:arr.unshift('a', 'b');
(头部添加 'a' 和 'b')splice(index, deleteCount, ...vals)
:在指定索引位置删除deleteCount
个元素,并添加 0~n 个元素(deleteCount
为 0 时仅添加)
示例:arr.splice(3, 0, 100);
(在索引 3 处插入 100,不删除元素)
修改数据
基于索引直接修改:数组名[索引] = 新值;
示例:arr[0] = 'aa';
(修改索引 0 的元素为 'aa')删除数据
pop()
:删除尾部元素,返回被删除元素
示例:let val = arr.pop();
shift()
:删除头部元素,返回被删除元素
示例:let firstVal = arr.shift();
splice(index, deleteCount)
:从索引index
开始删除deleteCount
个元素,返回被删除元素组成的数组
示例:let deleted = arr.splice(1, 2);
(删除索引 1 开始的 2 个元素)
查询数据
- 基于索引获取:
数组名[索引]
示例:let val = arr[1];
(获取索引 1 的元素) indexOf(val)
:返回val
在数组中第一次出现的索引(不存在返回 - 1)
示例:let idx = arr.indexOf(10);
lastIndexOf(val)
:返回val
在数组中最后一次出现的索引(不存在返回 - 1)
示例:let lastIdx = arr.lastIndexOf(10);
- 基于索引获取:
获取数组长度
语法:数组名.length
示例:console.log(arr.length);
3. 数组的遍历方式
数组有多种遍历方式,适用于不同场景:
for i(基于索引的遍历
for (let i = 0; i < arr.length; i++) {console.log(arr[i]); // 访问索引i的元素 }
for...of(基于值的遍历)
适用于可迭代对象(数组原型链含Symbol.iterator
),直接遍历元素值:for (let val of arr) {console.log(val); // 直接获取元素值 }
for...in(基于索引的遍历,不推荐用于数组)
主要用于对象遍历,遍历数组时获取索引(字符串类型):for (let index in arr) {console.log(arr[index]); // 通过索引字符串访问元素 }
键 / 值 / 键值对遍历(通过迭代器)
keys()
:获取索引组成的迭代器
示例:for (let index of arr.keys()) { console.log(index); }
values()
:获取元素值组成的迭代器
示例:for (let val of arr.values()) { console.log(val); }
entries()
:获取[索引, 值]
组成的迭代器
示例:for (let [index, val] of arr.entries()) { console.log(index, val); }
forEach(consumer)
遍历并消费每个元素,consumer
接收参数(元素、索引、数组本身):arr.forEach((val, index) => {console.log(index, val); // 遍历每个元素及索引 });
4. 数组的常见方法
includes(val):判断
val
是否为数组元素,返回布尔值
示例:console.log(arr.includes(10));
(判断 10 是否在数组中)join(sep=','):按指定分隔符拼接数组元素,返回字符串
示例:console.log(arr.join(':'));
(用 ":" 拼接元素)reverse():反转数组元素,修改原数组
示例:arr.reverse();
(数组元素反转)slice(start, stop):截取数组片段(从
start
到stop
前,不包含stop
),返回新数组(stop
支持负数,代表从尾部计数)
示例:console.log(arr.slice(2, 4));
(截取索引 2 到 3 的元素)sort(comparator):排序数组(默认按字符串自然顺序,可通过
comparator
自定义)- 升序:
(a, b) => a - b
- 降序:
(a, b) => b - a
示例:arr.sort((a, b) => b - a);
(降序排序)
- 升序:
5. 数组的高阶方法
高阶方法接收函数作为参数,返回处理后的结果:
filter(predicate):过滤并保留满足条件的元素,返回新数组(
predicate
为判断函数,返回布尔值)
示例:let nums = arr.filter(a => typeof a === 'number');
(筛选所有数字元素)map(functional):对每个元素进行映射处理,返回新数组(
functional
为处理函数,返回映射后的值)
示例:let doubled = nums.map(a => a * 2);
(所有数字乘以 2)find(predicate):查找满足条件的第一个元素,找不到返回
undefined
示例:let firstLarge = arr.find(a => a > 100);
(查找第一个大于 100 的元素)findIndex(predicate):查找满足条件的第一个元素的索引,找不到返回
-1
示例:let idx = arr.findIndex(a => a > 100);
(查找第一个大于 100 的元素索引)findLast(predicate):查找满足条件的最后一个元素,找不到返回
undefined
示例:let lastLarge = arr.findLast(a => a > 100);
findLastIndex(predicate):查找满足条件的最后一个元素的索引,找不到返回
-1
示例:let lastIdx = arr.findLastIndex(a => a > 100);
some(predicate):判断数组中是否有至少一个元素满足条件,返回布尔值(空数组返回
false
)
示例:console.log(arr.some(a => a > 100));
every(predicate):判断数组中所有元素是否都满足条件,返回布尔值(空数组返回
true
)
示例:console.log(arr.every(a => a > 0));
reduce(functional, initValue?):对数组元素进行累积计算,返回结果(
functional
为累积函数,接收上一轮结果和当前元素)- 无
initValue
:首次计算用数组前两个元素,后续用上一轮结果和下一个元素 - 有
initValue
:首次计算用initValue
和第一个元素
示例(求数组最大 / 最小值):
let [max, min] = arr.reduce((acc, curr) => {return [Math.max(acc[0], curr), Math.min(acc[1], curr)]; }, [-Infinity, Infinity]);
- 无
6. 数组的解构赋值
按规则快速提取数组元素并赋值:
基本语法:
let [变量1, 变量2, ...] = 数组;
(变量与数组元素按位置对应)
示例:let [a, b, c] = [1, 2, 3];
(a=1, b=2, c=3)跳过元素:用逗号跳过不需要的元素
示例:let [x, , y] = [1, 2, 3];
(x=1, y=3)默认值:解构到
undefined
时使用默认值
示例:let [a, b = 10] = [5];
(a=5, b=10)剩余元素:
...变量
接收剩余元素(只能在最后,且仅出现一次)
示例:let [a, ...rest] = [1, 2, 3];
(a=1, rest=[2, 3])应用:交换变量值
示例:[a, b] = [b, a];
(交换 a 和 b 的值)
7. 数组的展开运算符(...)
将数组元素展开为独立值,用于合并、传递参数等:
求数组最大值:
Math.max(...arr1, ...arr2)
(展开多个数组元素作为参数)
示例:let max = Math.max(...[1, 3, 5], ...[2, 4]);
(max=5)合并数组:
let newArr = [...arr1, ...arr2];
示例:let combined = [...[1,2], ...[3,4]];
(combined=[1,2,3,4])向数组添加元素:
arr1.push(...arr2);
(将 arr2 元素添加到 arr1 尾部)
8. 数组扁平化(flat ())
将嵌套数组展开为一维数组,参数为展开深度(默认 1,Infinity
表示完全展开)
示例:let flatArr = [1, [2, [3]]].flat(2);
(flatArr=[1,2,3])
二、JavaScript 对象
1. 对象的创建方式
字面量定义
语法:let 对象名 = { 键1: 值1, 键2: 值2, ... };
(键名符合标识符规则可省略引号,否则需用引号;纯数字也可作为键)
示例:let obj = {name: '张三',age: 20,"birth-day": "1990-10-1", // 含特殊字符的键需用引号3: 10, // 数字键speak: function() { console.log(this.name); } };
构造方法定义(new Object ())
语法:let 对象名 = new Object();
(创建空对象,后续添加属性)
2. 对象的基本操作
包括添加、修改、删除、查询属性:
添加 / 修改属性
- 用
.
操作符:对象名.键 = 值;
(键需符合标识符规则)
示例:obj.gender = '男';
- 用
[]
操作符:对象名['键'] = 值;
(键含特殊字符或动态时使用)
示例:obj['birth-day'] = '1990-10-1';
- 用
删除属性
语法:delete 对象名.键;
或delete 对象名['键'];
示例:delete obj['birth-day'];
查询属性
- 用
.
操作符:对象名.键
示例:console.log(obj.name);
- 用
[]
操作符:对象名['键']
示例:console.log(obj['age']);
- 用
3. 对象的遍历方式
for...in 遍历(键遍历)
遍历对象的所有可枚举属性(包括原型链属性,需注意筛选自身属性)
示例:for (let key in obj) {if (obj.hasOwnProperty(key)) { // 筛选自身属性console.log(key, obj[key]);} }
键遍历(Object.keys ())
返回对象自身所有可枚举键组成的数组,再用for...of
遍历
示例:for (let key of Object.keys(obj)) {console.log(key, obj[key]); }
值遍历(Object.values ())
返回对象自身所有可枚举值组成的数组
示例:for (let val of Object.values(obj)) { console.log(val); }
键值对遍历(Object.entries ())
返回对象自身所有可枚举键值对[键, 值]
组成的数组
示例:for (let [key, val] of Object.entries(obj)) {console.log(key, val); }
4. 对象的简写
函数属性简写:对象中函数属性可省略
function
关键字
示例:{ speak() { console.log(this.name); } }
(等价于speak: function() {}
)键值名相同简写:当属性的键名与变量名相同时,可省略
: 变量
示例:let name = '张三', age = 20; let obj = { name, age }; // 等价于 { name: name, age: age }
5. 属性名表达式
当键名动态时,用 [表达式]
定义属性(表达式结果作为键名)
示例:
let attr = 'name';
let obj = { [attr]: '张三' }; // 等价于 { name: '张三' }
6. 让对象可迭代(支持 for...of)
对象需包含 Symbol.iterator
方法(返回迭代器),迭代器通过 yield
输出元素
示例:
let myArray = {values: [],add(val) { this.values.push(val); },[Symbol.iterator]: function* () { // 生成器函数作为迭代器for (let val of this.values) { yield val; }}
};
myArray.add(1);
myArray.add(2);
for (let val of myArray) { console.log(val); } // 可遍历,输出1、2
7. 对象的解构赋值
按键名提取对象属性并赋值:
基本语法:
let { 键1: 变量1, 键2: 变量2, ... } = 对象;
(键名与对象属性匹配)
示例:let { name: x, age: y } = obj;
(x=obj.name, y=obj.age)默认值:属性不存在时使用默认值
示例:let { birth: z = '1990-1-1' } = obj;
(若 obj 无 birth 属性,z = 默认值)剩余属性:
...变量
接收剩余属性(组成新对象)
示例:let { name: x, ...rest } = obj;
(rest 包含除 name 外的所有属性)
JavaScript 数组与对象操作作业题整理
一、嵌套数组对象解构
题目:将嵌套的数组对象 [{ id: 1, data: { name: 'John' } }, { id: 2, data: { name: 'Doe' } }]
解构为变量 name1
(值为 John)和 name2
(值为 Doe)。
代码实现:
let arr = [{ id: 1, data: { name: 'John' } }, { id: 2, data: { name: 'Doe' } }];
// 多层解构:先解构数组元素,再解构data对象,最后提取name属性
let [{ data: { name: name1 } }, { data: { name: name2 } }] = arr;
console.log(name1, name2); // 输出:John Doe
二、嵌套数组解构
题目:将嵌套数组 [1, [2, 3], [4, [5, 6]]]
解构为变量 a、b、c
,使得 console.log(a, b, c)
输出 1 2 6
。
代码实现:
let val = [1, [2, 3], [4, [5, 6]]];
// 按层级解构,跳过不需要的元素
let [a, [b], [, [, c]]] = val;
console.log(a, b, c); // 输出:1 2 6
三、筛选并处理学生姓名
题目:现有数组存放多个学生名字,获取 2 个字的学生,并将名字格式化为 “张 三” 形式(如 “张三”→“张 三”)。
代码实现:
let names = ['李华', '张菲菲', '李明华', '张三'];
let result = names.filter(name => name.length === 2) // 筛选2个字的名字.map(name => name[0] + ' ' + name[1]); // 拆分名字并添加空格
console.log(result); // 输出:['李 华', '张 三']
四、处理数字数组并求和
题目:现有数字数组,获取所有大于 100 的数字,扩大 3 倍后计算总和。
代码实现:
let nums = [1, 5445, 6, 88, 54, 122];
let sum = nums.filter(num => num > 100) // 筛选大于100的数字.map(num => num * 3) // 扩大3倍.reduce((acc, curr) => acc + curr, 0); // 计算总和
console.log(sum); // 输出:(5445×3 + 122×3) = 16641
五、验证数组中是否有奇数
题目:判断数字数组中是否存在奇数。
代码实现:
let nums1 = [2, 4, 6, 8, 10, 11];
// 使用some方法判断是否有满足条件的元素(奇数)
let hasOdd = nums1.some(num => num % 2 === 1);
console.log(hasOdd ? '有奇数' : '无奇数'); // 输出:有奇数
六、统计奇偶数个数
题目:统计数字数组中奇数和偶数的个数。
代码实现:
let nums2 = [1, 2, 4, 5, 6, 88, 77];
// 使用reduce累加奇偶数个数,初始值为[奇数计数, 偶数计数]
let count = nums2.reduce((acc, num) => {num % 2 === 1 ? acc[0]++ : acc[1]++;return acc;
}, [0, 0]);
console.log(count); // 输出:[3, 4](3个奇数,4个偶数)
七、解构赋值交换变量
题目:使用数组解构赋值交换 a = 3
和 b = 4
的值。
代码实现:
let a1 = 3, b1 = 4;
// 解构赋值交换变量
[a1, b1] = [b1, a1];
console.log(a1, b1); // 输出:4 3
八、计算数组最大 / 最小值
题目:使用 reduce
一次性计算数组中所有数字的最大值和最小值。
代码实现:
let nums11 = [78, 45, 999, 45, 2, 3, 4, 1.789];
// 使用reduce同时追踪最大值和最小值,初始值为[-Infinity, Infinity]
let [max, min] = nums11.reduce((acc, num) => {return [Math.max(acc[0], num), Math.min(acc[1], num)];
}, [-Infinity, Infinity]);
console.log(max, min); // 输出:999 1.789
九、按数据类型分组
题目:将数组 [1, 2, "abc", "35", 45, "x" , true, false, [1, 2] , {a:1, b:2} ]
按类型分组,结果格式为:
{number: [1, 2, 45],string: ["abc", "35", "x"],boolean: [true, false],object: [[1, 2], {a:1, b:2}]
}
代码实现:
let data1 = [1, 2, "abc", "35", 45, "x", true, false, [1, 2], {a:1, b:2}];
let grouped = data1.reduce((acc, item) => {const type = typeof item;// 特殊处理:数组和对象的typeof均为'object',统一归入object分组if (type === 'number') acc.number.push(item);else if (type === 'string') acc.string.push(item);else if (type === 'boolean') acc.boolean.push(item);else if (type === 'object') acc.object.push(item);return acc;
}, { number: [], string: [], boolean: [], object: [] });
console.log(grouped); // 输出符合要求的分组结果
十、数据格式转换
题目:将以下数据格式转换为指定格式:
- 原数据:
{meta: { name: "姓名", sex: "性别", score: "成绩" },data: [["张三", "男", 85],["李四", "男", 77],["王五", "女", 79]] }
- 目标格式:
[{ "姓名": "张三", "性别": "男", "成绩": 85 },{ "姓名": "李四", "性别": "男", "成绩": 77 },{ "姓名": "王五", "性别": "女", "成绩": 79 } ]
代码实现:
let data2 = {meta: { name: "姓名", sex: "性别", score: "成绩" },data: [["张三", "男", 85], ["李四", "男", 77], ["王五", "女", 79]]
};
// 解构meta中的字段名
let { meta: { name: key1, sex: key2, score: key3 } } = data2;
// 映射data数组为对象数组
let transformed = data2.data.map(item => {let [val1, val2, val3] = item; // 解构数组元素return { [key1]: val1, [key2]: val2, [key3]: val3 }; // 使用变量作为键名
});
console.log(transformed); // 输出目标格式数组