javascript 数组(千字长文)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在 JavaScript 开发中,数组(Array)是处理数据的核心工具之一。无论是处理用户输入、操作 DOM 节点,还是构建复杂的数据结构,数组都扮演着不可替代的角色。对于编程初学者而言,理解数组的特性与常用方法是迈向进阶开发的关键一步;而中级开发者则可以通过深入掌握其底层原理与高级技巧,进一步提升代码的效率与可维护性。本文将从基础到进阶,系统性地解析 JavaScript 数组的各个方面,并通过实际案例帮助读者巩固知识。


一、数组的基础概念与创建方式

1.1 什么是 JavaScript 数组?

JavaScript 数组是一个有序的集合,可以存储多个值,并通过索引(index)快速访问这些值。想象一个书架上的书,每本书的位置由编号确定,数组中的元素也类似,每个元素都有一个从 0 开始递增的索引。例如:

const books = ["JavaScript权威指南", "算法图解", "设计模式"];  
console.log(books[0]); // 输出:"JavaScript权威指南"  

这里 books 就是一个数组,books[0] 表示第一个元素。

1.2 创建数组的多种方式

JavaScript 提供了多种创建数组的方法:

  1. 直接赋值法
    const fruits = ["apple", "banana", "orange"];  
    
  2. 构造函数法
    const numbers = new Array(3); // 创建长度为3的空数组  
    numbers[0] = 10; // 需要手动赋值  
    
  3. 动态生成法
    const evenNumbers = Array.from({ length: 5 }, (_, index) => (index + 1) * 2);  
    // 输出:[2, 4, 6, 8, 10]  
    

    这里 Array.from() 结合映射函数,可以高效生成特定模式的数组。


二、数组的常用操作方法

2.1 增删改查的核心方法

增:push()、unshift()

  • push() 在数组末尾添加元素:
    let arr = [1, 2];  
    arr.push(3); // arr 变为 [1,2,3]  
    
  • unshift() 在数组开头添加元素:
    arr.unshift(0); // arr 变为 [0,1,2,3]  
    

删:pop()、shift()

  • pop() 删除末尾元素:
    arr.pop(); // 删除3后,arr 变为 [0,1,2]  
    
  • shift() 删除开头元素:
    arr.shift(); // 删除0后,arr 变为 [1,2]  
    

改:通过索引直接赋值

arr[0] = 100; // arr 变为 [100,2]  

查:通过索引或方法遍历

for (let i = 0; i < arr.length; i++) {  
  console.log(arr[i]); // 逐个输出元素  
}  

2.2 高级遍历与转换方法

map():转换数组元素

map() 方法会遍历数组中的每个元素,返回一个新数组,适合数据格式化场景:

const prices = [19.9, 29.9, 39.9];  
const taxedPrices = prices.map(price => price * 1.08);  
// taxedPrices 结果:[21.492, 32.292, 43.092]  

filter():筛选符合条件的元素

const evenNumbers = [1,2,3,4,5].filter(num => num % 2 === 0);  
// evenNumbers 结果:[2,4]  

reduce():聚合数据

reduce() 可以将数组元素“缩减”为单一值,常用于求和、统计等场景:

const sum = [1,2,3,4,5].reduce((total, num) => total + num, 0);  
// sum 结果:15  

find() 与 findIndex():精准查找

const users = [  
  { id: 1, name: "Alice" },  
  { id: 2, name: "Bob" }  
];  
const foundUser = users.find(user => user.name === "Bob");  
// foundUser 结果:{ id:2, name:"Bob" }  

三、数组的高级特性与性能优化

3.1 数组的可变性与不可变性

JavaScript 数组是**可变(mutable)**的,这意味着修改数组会直接改变原始数据。例如:

let arr = [1,2,3];  
arr.push(4); // 原数组被修改  

但在函数式编程中,推荐使用不可变方法(如 map() 返回新数组),避免副作用:

const newArr = [...arr, 4]; // 使用扩展运算符创建新数组  

3.2 浅拷贝与深拷贝的陷阱

直接赋值 = 或扩展运算符 ... 会创建浅拷贝,即对象元素仍指向同一内存地址:

const arr1 = [{ name: "A" }];  
const arr2 = [...arr1];  
arr2[0].name = "B";  
console.log(arr1[0].name); // 输出:"B"(因为引用未变)  

要实现深拷贝,可以使用 JSON.parse(JSON.stringify(...)) 或第三方库:

const deepCopy = JSON.parse(JSON.stringify(arr1));  

3.3 ES6 新特性:展开运算符与解构赋值

展开运算符(...)

const combined = [1,2, ...[3,4], 5]; // 合并数组  
// combined 结果:[1,2,3,4,5]  

解构赋值

快速提取数组元素:

const [first, second] = [10, 20];  
console.log(first); // 10  

四、常见问题与解决方案

4.1 数组去重

传统方法使用 filter()

const unique = arr => arr.filter((item, index) => arr.indexOf(item) === index);  

ES6 方法更简洁:

const uniqueES6 = [...new Set([1,2,2,3])]; // 结果:[1,2,3]  

4.2 合并两个数组

const merged = arr1.concat(arr2); // 或使用扩展运算符 [...arr1, ...arr2]  

4.3 判断是否为数组

避免使用 instanceof,改用 Array.isArray()

Array.isArray([]); // true  

五、实战案例:构建一个购物车系统

5.1 需求分析

假设需要实现一个购物车,支持添加、删除商品,并计算总价。

5.2 代码实现

class ShoppingCart {  
  constructor() {  
    this.items = [];  
  }  

  addItem(item) {  
    this.items.push(item);  
  }  

  removeItem(index) {  
    this.items.splice(index, 1);  
  }  

  calculateTotal() {  
    return this.items.reduce((total, item) => total + item.price, 0);  
  }  
}  

// 使用示例  
const cart = new ShoppingCart();  
cart.addItem({ name: "Coffee", price: 3.5 });  
console.log(cart.calculateTotal()); // 3.5  

六、总结

JavaScript 数组作为开发中高频使用的数据结构,其灵活性与强大性往往被低估。从基础的增删改查到高级的函数式编程技巧,掌握数组的特性能够显著提升代码质量与开发效率。对于初学者,建议从简单操作入手,逐步结合实际项目练习;中级开发者则可以深入研究性能优化与设计模式,例如结合数组实现队列、栈等抽象数据类型。通过持续实践,数组将成为你手中得心应手的工具,助力解决各类编程挑战。


通过本文的讲解,希望读者能够系统性地理解 JavaScript 数组的使用场景与核心技巧。在后续学习中,建议结合 MDN 文档与开源项目,进一步探索数组的更多可能性。

最新发布