javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS数组指南

JavaScript数组从入门到实战完全指南

作者:葬送的代码人生

在JavaScript中数组是一种非常常用的数据结构,用于存储和操作一系列的值,对数组进行分类和汇总是一个常见的需求,特别是在处理数据时,这篇文章主要介绍了JavaScript数组从入门到实战的相关资料,需要的朋友可以参考下

前言

数组是 JavaScript 中最常用的数据结构之一,也是面试中的高频考点。本文将从实际代码出发,系统讲解 JavaScript 数组的核心概念、常用方法和高级技巧,帮助你彻底掌握这一重要知识点。

一、认识数组

1.1 什么是数组

数组(Array)是一段连续的存储空间,用于存储有序的元素集合。在 JavaScript 中,数组是「开箱即用」的数据结构,无需额外引入。

const arr = [1, 2, 3, 4, 5];
console.log(arr);  // [1, 2, 3, 4, 5]

JavaScript 的数组非常灵活:

const mixedArr = [1, 'hello', true, { name: 'Alice' }, [1, 2, 3]];

1.2 内存视角

数组的底层是连续的内存空间,通过「起始地址 + 偏移量」快速定位元素。这使得数组的随机访问效率极高,时间复杂度为 O(1)。

const arr = ['a', 'b', 'c', 'd', 'e'];
console.log(arr[0]);  // 'a' - 通过索引快速访问
console.log(arr[3]);  // 'd'

1.3 ADT 抽象数据类型

在计算机科学中,我们常用 ADT(Abstract Data Type,抽象数据类型) 来描述数据结构:

连续的存储空间 + 特定的操作

以数组为例:

这种抽象方式让我们专注于「做什么」,而不必关心「怎么做」。

二、数组的创建方法

2.1 字面量创建

最常用、最简洁的方式:

const arr = [1, 2, 3, 4, 5];

2.2 构造函数创建

使用 new Array() 构造函数:

const arr = new Array();        // 空数组
const arr2 = new Array(7);       // 指定长度为7的空数组
console.log(arr2);              // [empty × 7]

注意new Array(7) 创建的是「空位置」,不是 undefined

const arr = new Array(7);
console.log(arr[0]);            // undefined
console.log(arr.length);        // 7

2.3 fill 方法初始化

对于需要初始值的数组,使用 fill() 方法:

const arr = new Array(7).fill(0);
console.log(arr);               // [0, 0, 0, 0, 0, 0, 0]

三、增删操作:push、pop、unshift、shift

JavaScript 数组提供了四个基本增删方法,它们都会修改原数组

3.1 push - 尾部添加

const arr = ['a', 'b', 'c'];
arr.push('d');
console.log(arr);               // ['a', 'b', 'c', 'd']
console.log(arr.push('e'));     // 返回新长度: 5

3.2 pop - 尾部删除

const arr = ['a', 'b', 'c', 'd', 'e'];
console.log(arr.pop());         // 返回被删除元素: 'e'
console.log(arr);               // ['a', 'b', 'c', 'd']

3.3 unshift - 头部添加

const arr = [1, 2, 3];
arr.unshift(0);
console.log(arr);               // [0, 1, 2, 3]

3.4 shift - 头部删除

const arr = [1, 2, 3, 4, 5];
console.log(arr.shift());       // 返回被删除元素: 1
console.log(arr);               // [2, 3, 4, 5]

3.5 方法对比

方法操作位置返回值是否修改原数组
push尾部添加新数组长度
pop尾部删除被删除元素
unshift头部添加新数组长度
shift头部删除被删除元素

3.6 纯函数概念

以上四个方法都会修改原数组,属于非纯函数。纯函数的特点是:

// 非纯函数 - 修改原数组
function pushImpure(arr, item) {
  arr.push(item);
  return arr;
}

// 纯函数 - 不修改原数组
function pushPure(arr, item) {
  return [...arr, item];
}

四、数组遍历方法

4.1 for 循环

最传统的方式,性能最好但可读性较差:

const arr = [1, 2, 3, 4, 5];

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

4.2 for...of 循环

语义更好,专为可迭代对象设计:

const arr = [1, 2, 3, 4, 5];

for (const item of arr) {
  console.log(item);
}

4.3 forEach 方法

功能强大,但无法中断遍历(不支持 breakcontinue):

const arr = ['苹果', '香蕉', '橙子'];

arr.forEach((item, index, self) => {
  console.log(`${index}: ${item}`);
});

回调参数说明

参数说明
item当前遍历的元素
index当前元素的索引
self数组本身

五、高阶方法:map、filter、every、some、reduce

这些方法都基于 forEach 实现,都返回新数组(除了 everysome 返回布尔值),都是纯函数

5.1 map - 元素转换

将数组中的每个元素映射为新值,返回全新数组:

const arr = [1, 2, 3, 4, 5];

// 将每个元素乘以2
const doubled = arr.map(item => item * 2);
console.log(doubled);           // [2, 4, 6, 8, 10]

// 元素类型转换
const strings = arr.map(item => String(item));
console.log(strings);           // ['1', '2', '3', '4', '5']

5.2 filter - 条件筛选

保留满足条件的元素,返回新数组:

const arr = [1, 2, 3, 4, 5];

// 筛选偶数
const evens = arr.filter(item => item % 2 === 0);
console.log(evens);             // [2, 4]

// 筛选大于3的元素
const greaterThan3 = arr.filter(item => item > 3);
console.log(greaterThan3);     // [4, 5]

5.3 every - 全量判断

检查是否所有元素都满足条件:

const arr = [1, 2, 3, 4, 5];

// 检查是否全为正数
console.log(arr.every(item => item > 0));  // true

// 检查是否全为偶数
console.log(arr.every(item => item % 2 === 0));  // false

特点:遇到不满足条件的元素会立即停止(短路)。

5.4 some - 存在判断

检查是否存在至少一个满足条件的元素:

const arr = [1, 2, 3, 4, 5];

// 是否存在偶数
console.log(arr.some(item => item % 2 === 0));  // true

// 是否全为负数
console.log(arr.some(item => item < 0));  // false

特点:遇到满足条件的元素会立即停止(短路)。

5.5 reduce - 累积归约

将数组元素累积为单一值,是最强大、最灵活的方法:

const arr = [1, 2, 3, 4, 5];

// 求和
const sum = arr.reduce((pre, cur) => pre + cur);
console.log(sum);               // 15

// 求积
const product = arr.reduce((pre, cur) => pre * cur, 1);
console.log(product);           // 120

// 带初始值
const sumWithInit = arr.reduce((pre, cur) => pre + cur, 10);
console.log(sumWithInit);       // 25(10 + 1 + 2 + 3 + 4 + 5)

参数说明

参数说明
pre累积结果(初始值为第一次迭代时的 pre)
cur当前元素
initialValue初始值(可选)

5.6 方法选择指南

场景推荐方法
元素转换map
条件筛选filter
全量判断every
存在判断some
累积计算reduce

5.7 链式调用

多个方法可以链式使用:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const result = numbers
  .filter(num => num % 2 === 0)  // [2, 4, 6, 8, 10]
  .map(num => num * 10)          // [20, 40, 60, 80, 100]
  .reduce((a, b) => a + b);     // 300

console.log(result);

六、原型链与 Array.prototype

在 JavaScript 中,所有数组实例都共享 Array.prototype 上的方法。这就是原型链的体现:

const arr = new Array();

console.log(typeof Array);           // "function" - Array 是构造函数
console.log(Array.prototype);        // 数组原型对象
console.log(Array.prototype.__proto__);  // Object.prototype

原型链结构

arr (数组实例)
  ↓ [[Prototype]]
Array.prototype (包含 push, pop, map, filter 等方法)
  ↓ [[Prototype]]
Object.prototype (所有对象的终极原型)
  ↓ [[Prototype]]
null (原型链终点)

方法来源

当你调用数组方法时:

const arr = [1, 2, 3];
arr.push(4);  // push 方法来自 Array.prototype

七、二维数组

二维数组本质上是「数组的数组」,常用于表示矩阵、表格等结构:

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

// 访问元素
console.log(matrix[0][0]);  // 1
console.log(matrix[1][2]);  // 6

创建二维数组的坑

使用 fill 创建二维数组时要小心:

// 错误方式
const wrong = new Array(3).fill([]);
wrong[0].push(1);
console.log(wrong);  // [[1], [1], [1]] - 三个数组共享同一个引用!

// 正确方式
const correct = Array.from({ length: 3 }, () => []);
correct[0].push(1);
console.log(correct);  // [[1], [], []] - 互不影响

八、综合实战

8.1 数组去重

const arr = [1, 2, 2, 3, 3, 3, 4, 5, 5];

// 方式一:Set
const unique1 = [...new Set(arr)];

// 方式二:filter
const unique2 = arr.filter((item, index) => arr.indexOf(item) === index);

// 方式三:reduce
const unique3 = arr.reduce((pre, cur) => 
  pre.includes(cur) ? pre : [...pre, cur], []);

console.log(unique1);  // [1, 2, 3, 4, 5]

8.2 数组扁平化

const nested = [1, [2, [3, [4, [5]]]]];

// 方式一:flat
const flat1 = nested.flat(Infinity);

// 方式二:reduce
function flatten(arr) {
  return arr.reduce((pre, cur) => 
    Array.isArray(cur) ? [...pre, ...flatten(cur)] : [...pre, cur], []);
}

console.log(flatten(nested));  // [1, 2, 3, 4, 5]

8.3 统计元素出现次数

const arr = ['a', 'b', 'a', 'c', 'b', 'a'];

const count = arr.reduce((pre, cur) => {
  pre[cur] = (pre[cur] || 0) + 1;
  return pre;
}, {});

console.log(count);  // { a: 3, b: 2, c: 1 }

九、总结

JavaScript 数组是前端开发中最重要的数据结构之一。本文涵盖的核心知识点:

  1. ADT 抽象数据类型:连续存储空间 + 特定操作
  2. 增删方法pushpopunshiftshift
  3. 遍历方法forfor...offorEach
  4. 高阶方法mapfiltereverysomereduce
  5. 原型链:理解 Array.prototype 的作用
  6. 二维数组:矩阵结构与常见坑点

熟练掌握这些内容,不仅能应对面试考察,更能在实际开发中写出简洁、高效的代码。

参考资料

到此这篇关于JavaScript数组从入门到实战完全指南的文章就介绍到这了,更多相关JS数组指南内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文