[id_[id_14[id_94[]]]]
一、数组的本质:不只是简单的列表1.1 数组是什么?
在编程领域,数组被视为一种独特的结构,它由一系列按顺序排列的数据构成。这种结构与一般对象有所区别,其内部元素可以通过数字编号(起始值为0)进行定位和访问。
const fruits = ['苹果', '香蕉', '橙子'];
console.log[id_1906074320]0]); // "苹果"
然而,有趣的是,这种数组实际上要复杂得多。它并非像C++或Java那样采用严格的内存连续分配方式,而是采用了一种更为灵活的动态结构。
1.2 数组的创建方式
[]
数组字面量(最常用):
const arr = [1, 2, 3];
[]
const arr = new Array(5); // 创建长度为5的空数组
const arr2 = new Array(1, 2, 3); // [1,2,3]
Array上的静态方法:
const arr = Array.of(1, 2, 3[id_1941992320]; // [1, 2, 3]
const arr2 = Array.from(new Array(3),(val,index) => String.fromCharCode(index+65)); // ['A','B','C']
这里存在一个需要留意的陷阱:当你执行new Array(5)操作时,所得到的并非一个包含五个元素的数组,而是五个所谓的“空位”(empty slots)。
const arr = new Array(5);
console.log(arr); // [empty × 5]
在使用for...in循环遍历此类数组时,会遇到障碍,原因是其中的空槽位实际上并不具备任何属性。
for(let key in arr) {
console.log(key, arr[key]); // 什么都不会输出
}
解决办法是用fill方法填充:
const arr = new Array(5).fill(undefined);
for(let key in arr) {
console.log(key, arr[key]); // 现在可以正常输出了
}
二、数组的高级创建方式2.1 Array.of() 方法
Array.of()函数有效解决了由Array构造函数引起的参数处理不统一的问题。
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
new Array(7); // [empty × 7]
new Array(1, 2, 3); // [1, 2, 3]
2.2 Array.from() 方法
Array.from()功能更为卓越,能够将类数组对象或是可迭代对象成功转化为实际的数组形式。
// 从字符串创建数组
Array.from('foo'); // ["f", "o", "o"]
// 从Set创建数组
Array.from(new Set(['a', 'b'])); // ['a', 'b']
// 从Map创建数组
Array.from(new Map([[1, 2], [3, 4]])); // [[1, 2], [3, 4]]
// 创建字母表
const alphabet = Array.from(new Array(26),
(val,index) => String.fromCharCode(index+65)
);
console.log(alphabet); // ["A", "B", "C", ..., "Z"]
三、数组遍历的多种方式
遍历数组是日常开发中最常见的操作之一,提供了多种遍历方式:
3.1 传统的for循环(计数循环)
const arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
优点:性能最好,可以随时中断循环(使用break或)
缺点:代码略显冗长
类似的还有while循环
3.2 方法
arr.forEach(item => {
console.log(item);
});
优点:简洁明了
缺点:无法中途跳出循环(即使使用也只是跳出当前回调)
3.3 for...of循环
ES6引入的for...of循环让数组遍历更加优雅:
for(const item of arr) {
console.log(item);
}
如果需要同时获取索引和值,可以结合()方法:
for(const [index, value] of arr.entries()) {
console.log(index, value);
}
3.4 其他迭代方法
数组还提供了丰富的迭代方法:
四、数组的方法:函数式编程的利器
数组处理中,此方法堪称最为有力的手段之一,它能够将整个数组简化为一个单一的数值结果。
const sum = [1, 2, 3, 4].reduce((prev, curr) => prev + curr, 0);
console.log(sum); // 10
但的能力远不止于此,它可以实现很多复杂的功能:
4.1 数组转对象
const fruits = ['apple', 'banana', 'orange'];
const fruitMap = fruits.reduce((obj, fruit) => {
obj[fruit] = true;
return obj;
}, {});
console.log(fruitMap); 苹果、香蕉和橙子均不可更改,其属性值均为真。
4.2 实现分组
const people = [
{name: 'Alice', age: 21},
{name: 'Bob', age: 20},
{name: 'Charlie', age: 21}
];
const groupedByAge = people.reduce((acc, person) => {
const age = person.age;
if(!acc[age]) acc[age] = [];
acc[age].push(person);
return acc;
}, {});
console.log(groupedByAge);
// {
Bob的名字,年龄为20岁,被列入了禁止修改的名单中。
Alice,年龄21岁,与Charlie,同样21岁,被纳入了同一组。
// }
五、数组的扩展运算符:简洁而强大
ES6的扩展运算符...让数组操作变得更加简洁:
5.1 复制数组
const original = [1, 2, 3];
const copy = [...original];
5.2 合并数组
const arr1 = [1, 2];
const arr2 = [3, 4];
const合并后的数组为 [...arr1, ...arr2];// [1, 2, 3, 4]
5.3 函数参数传递
const numbers = [1, 2, 3];
console.log(Math.max(...numbers)); // 3
5.4 替代apply方法
// 旧方式
function foo(x, y, z) {}
const args = [1, 2, 3];
foo.apply(null, args);
// 新方式
foo(...args);
六、数组的性能优化技巧
虽然数组非常灵活,但在处理大数据量时,性能问题不容忽视:
6.1 预分配数组大小
// 不推荐:动态扩容
const arr = [];
for(let i = 0; i < 1000000; i++) {
arr[i] = i;
}
// 推荐:预分配大小
const arr = new Array(1000000);
for(let i = 0; i < 1000000; i++) {
arr[i] = i;
}
6.2 避免在循环中修改数组长度
// 不推荐
for(let i = 0; i < arr.length; i++) {
if(someCondition) {
arr.splice(i, 1); // 修改了数组长度
i--; // 需要手动调整索引
}
}
// 推荐:从后往前遍历
for(let i = arr.length - 1; i >= 0; i--) {
if(someCondition) {
arr.splice(i, 1); // 不影响前面的索引
}
}
七、数组的"怪异"行为
数组有一些看似奇怪的行为,了解它们可以避免踩坑:
7.1 稀疏数组
const arr = [1, , 3]; // 注意中间的空位
console.log(arr.length); // 3
console.log(arr[1]); // undefined
console.log(1 in arr); // false - 说明这个位置没有元素
7.2 属性的特殊性
const arr = [1, 2, 3];
arr.length = 5;
console.log(arr); // [1, 2, 3, empty × 2]
arr.length = 2;
console.log(arr); // [1, 2] - 后面的元素被删除了
7.3 数组也是对象
const arr = [1, 2, 3];
arr.foo = 'bar';
console.log(arr.foo); // 'bar'
console.log(arr.length); // 3 - 非数字属性不影响length
八、现代中的数组新特性8.1 flat()和()
// 扁平化数组
const arr = [1, [2, [3]]];
console.log(arr.flat(2)); // [1, 2, 3]
// flatMap = map + flat(1)
const sentences = ["Hello world", "Good morning"];
const words = sentences.flatMap(s => s.split(' '));
console.log(words); 您好,世界,早上好。
8.2 Array..at()
const arr = [1, 2, 3];
console.log(arr.at(-1)); // 3 - 支持负索引
8.3 ()和()
const arr = [1, 2, 3, 2, 1];
console.log(arr.findLast(x => x === 2)); // 2 (最后一个2)
console.log(arr.findLastIndex(x => x === 2)); // 3
结语
数组表面看似简易,实则蕴含着深厚的内涵。它不仅涵盖了从基础的构建与遍历方法,还包括了高级的操作技巧和性能提升策略,在编程领域中扮演着举足轻重的角色。本文旨在帮助你更全面地洞察并熟练运用数组的多样特性和操作技巧。
数组作为一种常见的数据存储方式,在编程领域应用广泛。深入了解并精通其多种使用技巧,能够使你的编程工作更加精炼且效率更高。对于任何疑问或创意,你都可以在评论区发表意见,共同探讨。
扫一扫在手机端查看
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。


客服1