js中list存储

admin 104 0
在JavaScript中,通常使用数组(Array)实现类似列表的存储功能,数组可通过字面量[]或构造函数new Array()创建,支持动态调整长度,常用存储操作包括:push()在末尾添加元素,unshift()在开头添加,pop()删除末尾元素,shift()删除开头元素,并通过索引arr[index]访问或修改元素,数组可存储任意类型数据(如数字、字符串、对象等),并内置map()filter()等高阶方法处理数据,其有序性和动态特性使其适合存储和管理集合数据,是JavaScript中最基础且常用的数据结构之一。

JavaScript中的List存储:从数组到高级数据结构

在JavaScript开发中,"List"(列表)是最基础也最常用的数据结构之一,它用于存储有序的元素集合,支持动态增删改查操作,是处理数据流、缓存、队列等场景的核心工具,尽管JavaScript没有原生的"List"类型,但我们可以通过数组(Array)或自定义数据结构来实现List的功能,本文将从基础到进阶,全面解析JavaScript中List的存储与使用方法。

JavaScript中的List:数组的原生实现

在JavaScript中,数组(Array)是List最直接、最常用的实现方式,数组本身就是一个有序的列表,支持存储任意类型的元素(数字、字符串、对象,甚至其他数组),并提供了一系列内置方法来操作元素。

创建与初始化List

创建数组(List)有多种方式,最常见的是通过数组字面量或Array构造函数:

// 方式1:数组字面量(推荐)
const list1 = [1, 2, 3, "hello", { name: "Alice" }];
// 方式2:Array构造函数
const list2 = new Array(5); // 创建长度为5的空数组(元素为undefined)
const list3 = new Array(1, 2, 3); // 创建包含1, 2, 3的数组
// 方式3:Array.from(从类数组或可迭代对象创建)
const list4 = Array.from("hello"); // ['h', 'e', 'l', 'l', 'o']
const list5 = Array.from({ length: 3 }, (_, i) => i + 1); // [1, 2, 3]
// 方式4:扩展运算符
const list6 = [...list1]; // 创建list1的浅拷贝

List的基本操作:增删改查

数组的核心操作包括增、删、改、查,这些方法直接对应List的动态管理需求:

(1)查:访问元素

通过索引(从0开始)访问元素,JavaScript数组不支持直接使用负索引访问:

const list = [10, 20, 30, 40];
console.log(list[0]); // 10(第一个元素)
console.log(list[-1]); // undefined(JavaScript数组不支持负索引)
console.log(list[list.length - 1]); // 40(最后一个元素)
// 如果需要支持负索引,可以创建辅助函数
function getNegativeIndex(arr, index) {
  return index < 0 ? arr[arr.length + index] : arr[index];
}
console.log(getNegativeIndex(list, -1)); // 40
(2)增:添加元素
  • 尾部添加push()(返回新长度)

    const list = [1, 2];
    list.push(3); // list变为[1, 2, 3]
  • 头部添加unshift()(返回新长度)

    list.unshift(0); // list变为[0, 1, 2, 3]
  • 中间添加splice(start, deleteCount, ...items)(修改原数组,返回被删除元素)

    list.splice(2, 0, 1.5); // 在索引2处插入1.5,list变为[0, 1, 1.5, 2, 3]
  • 批量添加:使用扩展运算符或concat

    list = [...list, 4, 5]; // 尾部添加多个元素
    list = [6, 7, ...list]; // 头部添加多个元素
(3)删:删除元素
  • 尾部删除pop()(返回被删除元素)

    const removed = list.pop(); // removed=3,list变为[0, 1, 1.5, 2]
  • 头部删除shift()(返回被删除元素)

    const removed = list.shift(); // removed=0,list变为[1, 1.5, 2]
  • 中间删除splice(start, deleteCount)

    const removed = list.splice(1, 1); // 删除索引1处的元素(1.5),removed=[1.5],list变为[1, 2]
  • 条件删除:使用filter

    const list = [1, 2, 3, 4, 5];
    const filtered = list.filter(item => item % 2 === 0); // [2, 4]
(4)改:修改元素

直接通过索引赋值,或使用splice()替换:

list[0] = 100; // 直接修改,list变为[100, 2]
list.splice(1, 1, 200); // 替换索引1处的元素,list变为[100, 200]
// 批量修改
list.forEach((item, index) => {
  if (index % 2 === 0) list[index] = item * 2;
});

List的遍历方法

数组提供了多种遍历方式,适用于不同场景:

  • for循环:最灵活,支持索引和自定义终止条件

    for (let i = 0; i < list.length; i++) {
      console.log(list[i]);
    }
  • forEach:遍历每个元素,无返回值

    list.forEach((item, index) => console.log(`${index}: ${item}`));
  • map:返回新数组,对每个元素处理后存入新数组

    const doubled = list.map(item => item * 2); // [200, 400]
  • filter:返回符合条件的新数组

    const filtered = list.filter(item => item > 100); // [200]
  • reduce:累计计算,返回最终值(如求和、拼接)

    const sum = list.reduce((acc, item) => acc + item, 0); // 600
  • for...of:直接遍历元素值

    for (const item of list) {
      console.log(item);
    }
  • entries()、keys()、values():获取迭代器

    for (const [index, value] of list.entries()) {
      console.log(`${index}: ${value}`);
    }

性能考量:数组的"短板"与替代方案

虽然数组是List的天然选择,但其底层基于连续内存存储,导致在某些场景下性能不佳:

  • 中间插入/删除splice()shift()unshift()需要移动后续元素,时间复杂度为O(n)。
  • 头部操作shift()unshift()每次操作都需要重新索引整个数组,性能随数组长度增长而显著下降。

当需要频繁进行中间或头部操作时,可以考虑用链表(Linked List)替代。

自定义链表实现

class ListNode {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}
class LinkedList {
  constructor() {
    this.head = null;
    this.size = 0;
  }
  // 在头部添加元素
  addFirst(value) {
    this.head =

标签: #js #数组