JavaScript数据结构

目录

JavaScript数据结构

一、基础数据结构

1. 数组(Array)

2. 对象(Object)

二、ES6+ 高级数据结构

1. Map

2. Set

3. WeakMap 与 WeakSet

三、类型化数组(Typed Arrays)

四、其他数据结构实现

1. 栈(Stack)

2. 队列(Queue)

3. 链表(Linked List)

五、数据结构选择指南

六、最佳实践

JavaScript中的for循环

1. 传统 for 循环

语法

示例

特点

2. for...of 循环

语法

示例

特点

3. for...in 循环

语法

示例

特点

4. Array.prototype.forEach

语法

示例

特点

5. 性能与选择指南

性能对比

如何选择?

6. 常见陷阱

1. 修改数组长度

2. 闭包问题

3. 遍历稀疏数组


JavaScript数据结构


一、基础数据结构

1. 数组(Array)

  • 定义:有序元素集合,可存储任意类型值。

  • 创建方式

    let arr1 = [1, "a", true];      // 字面量
    let arr2 = new Array(3);        // 创建长度3的空数组(慎用)
  • 核心方法

    • 增删元素

      arr.push(4);        // 末尾添加 → [1, 2, 3, 4]
      arr.pop();          // 移除末尾 → [1, 2]
      arr.unshift(0);     // 开头添加 → [0, 1, 2]
      arr.shift();        // 移除开头 → [1, 2]
    • 操作数组

      arr.splice(1, 1, "x");  // 从索引1删除1个元素,插入"x" → [1, "x", 3]
      arr.slice(1, 3);         // 截取索引1到3(不包含3)→ ["x", 3]
      arr.concat([4, 5]);      // 合并数组 → [1, 2, 3, 4, 5]
    • 迭代与转换

      arr.map(x => x * 2);     // 映射新数组 → [2, 4, 6]
      arr.filter(x => x > 1);  // 过滤 → [2, 3]
      arr.reduce((sum, x) => sum + x, 0); // 累加 → 6
  • 注意事项

    • 稀疏数组:空位(如 new Array(3))可能引发意外行为。

    • 引用类型:数组赋值传递引用,需用 [...arr] 或 arr.slice() 克隆。


2. 对象(Object)

  • 定义:键值对集合,键为字符串或 Symbol。

  • 创建方式

    let obj1 = { name: "Alice", age: 25 }; // 字面量
    let obj2 = new Object();               // 构造函数
  • 核心操作

    • 增删查改

      obj.email = "alice@example.com"; // 添加属性
      delete obj.age;                  // 删除属性
      console.log("name" in obj);      // 检查属性是否存在 → true
    • 遍历

      Object.keys(obj);    // 返回键数组 → ["name", "email"]
      Object.values(obj);  // 返回值数组 → ["Alice", "alice@example.com"]
      for (let key in obj) { console.log(key, obj[key]); } // 遍历自身及原型链属性
  • 注意事项

    • 原型污染:避免修改 Object.prototype

    • 键顺序:ES6 后字符串键按插入顺序保留,但数字键优先排序。


二、ES6+ 高级数据结构

1. Map

  • 特点

    • 键可以是任意类型(对象、函数等)。

    • 保持插入顺序。

  • 核心方法

    let map = new Map();
    map.set("key", "value");    // 添加键值对
    map.get("key");             // 获取值 → "value"
    map.has("key");             // 检查存在 → true
    map.delete("key");          // 删除键值对
    map.size;                   // 获取条目数
  • 适用场景:需要复杂键或频繁增删键值对时,优于 Object。


2. Set

  • 特点:存储唯一值,自动去重。

  • 核心方法

    let set = new Set();
    set.add(1);                 // 添加值
    set.add(2);
    set.has(1);                 // 检查存在 → true
    set.delete(1);              // 删除值
    set.size;                   // 获取元素数量
  • 适用场景:去重、集合运算(并集、交集等)。


3. WeakMap 与 WeakSet

  • 特点

    • 弱引用:键必须是对象,不阻止垃圾回收。

    • 不可迭代:无 sizeclear() 或遍历方法。

  • 使用场景

    • WeakMap:存储对象关联的私有数据或元数据。

      let wm = new WeakMap();
      let obj = {};
      wm.set(obj, "secret");
    • WeakSet:标记对象(如跟踪已处理对象)。

      let ws = new WeakSet();
      ws.add(obj);

三、类型化数组(Typed Arrays)

用于处理二进制数据(如图像、音频),与 ArrayBuffer 配合使用。

  • 常见类型

    • Int8ArrayUint8Array(8位整数)

    • Int16ArrayFloat32Array 等。

  • 示例

    let buffer = new ArrayBuffer(16);      // 分配16字节内存
    let int32View = new Int32Array(buffer); // 32位整数视图(4个元素)
    int32View[0] = 42;

四、其他数据结构实现

JavaScript 未内置,但可通过基础结构模拟:

1. 栈(Stack)

  • 后进先出(LIFO),用数组实现:

    class Stack {constructor() { this.items = []; }push(element) { this.items.push(element); }pop() { return this.items.pop(); }peek() { return this.items[this.items.length - 1]; }
    }

2. 队列(Queue)

  • 先进先出(FIFO)

    class Queue {constructor() { this.items = []; }enqueue(element) { this.items.push(element); }dequeue() { return this.items.shift(); } // 时间复杂度 O(n)
    }

3. 链表(Linked List)

  • 节点链接实现

    class Node {constructor(value) {this.value = value;this.next = null;}
    }
    class LinkedList {constructor() { this.head = null; }append(value) { /* 实现添加逻辑 */ }
    }

五、数据结构选择指南

场景推荐数据结构理由
有序集合,需快速访问索引数组(Array)索引操作时间复杂度 O(1)
键值对,键为字符串或 Symbol对象(Object)语法简洁,查找速度快
键为任意类型,需维护插入顺序Map支持复杂键,有序
存储唯一值Set自动去重,集合运算高效
高频增删元素(如队列)链表(自定义实现)避免数组 shift() 的 O(n) 复杂度
二进制数据处理类型化数组(Typed Array)内存高效,适合底层操作

六、最佳实践

  1. 优先使用 ES6+ 数据结构:如 MapSet 替代传统对象和数组,提升代码可读性。

  2. 注意引用类型副作用:克隆数据避免意外修改。

  3. 性能敏感场景优化:如用 Int32Array 替代普通数组处理大量数值。

  4. 垃圾回收考虑:使用 WeakMap/WeakSet 管理对象关联数据,防止内存泄漏。


  

JavaScript中的for循环


1. 传统 for 循环

最基础的循环结构,通过明确的初始化条件迭代器控制循环。

语法

for (初始化; 条件; 迭代器) {// 循环体
}

示例

// 遍历数组
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {console.log(arr[i]); // 输出 1, 2, 3
}// 倒序循环
for (let i = arr.length - 1; i >= 0; i--) {console.log(arr[i]); // 输出 3, 2, 1
}

特点

  • 灵活控制:可自定义步长(如 i += 2)、跳过某次循环(continue)或提前退出(break)。

  • 性能优化:预存数组长度(如 let len = arr.length)避免重复计算。

  • 作用域:使用 let 声明变量时,每次循环会创建新的块级作用域。


2. for...of 循环

遍历可迭代对象(如数组、字符串、Map、Set、生成器等)的值。

语法

for (const value of iterable) {// 使用 value
}

示例

const arr = ['a', 'b', 'c'];
for (const val of arr) {console.log(val); // 输出 'a', 'b', 'c'
}// 遍历字符串
for (const char of 'Hello') {console.log(char); // 输出 H, e, l, l, o
}

特点

  • 简洁性:无需索引,直接获取值。

  • 支持异步:可与 await 结合使用(需在 async 函数中)。

  • 不适用于普通对象:默认对象不可迭代(除非自行实现 Symbol.iterator)。


3. for...in 循环

遍历对象的可枚举属性(包括原型链上的属性)。

语法

for (const key in object) {// 使用 key 访问属性值:object[key]
}

示例

const obj = { a: 1, b: 2 };
for (const key in obj) {console.log(key, obj[key]); // 输出 a 1, b 2
}// 遍历数组(不推荐!)
const arr = [1, 2, 3];
arr.foo = 'bar';
for (const key in arr) {console.log(key); // 输出 0, 1, 2, 'foo'
}

特点

  • 遍历对象属性:适合处理键值对。

  • 可能遍历原型链:需用 hasOwnProperty 过滤:

    for (const key in obj) {if (obj.hasOwnProperty(key)) {// 仅处理自身属性}
    }
  • 不保证顺序:现代引擎通常按属性添加顺序遍历,但复杂场景可能不一致。


4. Array.prototype.forEach

数组专用的高阶函数,遍历每个元素。

语法

array.forEach((value, index, array) => {// 循环体
});

示例

const arr = [1, 2, 3];
arr.forEach((value, index) => {console.log(index, value); // 输出 0 1, 1 2, 2 3
});

特点

  • 不可中断:无法使用 break 或 continue,需通过 return 跳过当前迭代。

  • 链式调用:可与其他数组方法(如 mapfilter)配合。

  • 异步陷阱:回调函数中的 await 不会暂停外层循环。


5. 性能与选择指南

性能对比

  • 最快:传统 for 循环(尤其预存长度时)。

  • 适中for...of(底层使用迭代器协议)。

  • 较慢forEach(函数调用开销)。

如何选择?

场景推荐方式
需要索引或复杂控制传统 for 循环
遍历数组值(无需索引)for...of
遍历对象属性for...in + 过滤
简单数组操作forEach
处理稀疏数组传统 for + 判空

6. 常见陷阱

1. 修改数组长度

const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {arr.pop(); // 可能导致无限循环或跳过元素
}

2. 闭包问题

for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i)); // 输出 3, 3, 3
}
// 解决:改用 let 或 IIFE

3. 遍历稀疏数组

const arr = [1, , 3]; // 中间是空位
arr.forEach(v => console.log(v)); // 输出 1, 3(跳过空位)
for (const v of arr) console.log(v); // 输出 1, undefined, 3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

魔改chromium——基础环境搭建

谷歌chromium环境要求详细文档 软件和环境要求&#xff0c;必须安装&#xff0c;硬性要求 系统环境&#xff1a;Windows 10&#xff0c;内存最小8GB&#xff0c;推荐16GB&#xff0c;NTFS格式磁盘最少100GB空间Git版本&#xff1a;安装最新版本即可&#xff0c;Git桌面端下载…

电子文档安全管理系统V6.0接口backup存在任意文件下载漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 电子文档安全管理系统 V6.0 reso…

5.3 MVVM模型

一、MVVM的基本概念 MVVM的基本概念&#xff1a;Model、View、ViewModel 组件职责示例内容Model封装业务数据User类&#xff0c;包含姓名、年龄属性View负责UI呈现XAML界面&#xff0c;包含数据绑定ViewModel连接View和Model&#xff0c;处理视图逻辑MainViewModel包含命令和…

python采集淘宝拍立淘按图搜索API接口,json数据示例参考

以下是关于淘宝拍立淘按图搜索API接口的详细说明及JSON数据示例&#xff1a; 一、接口概述 淘宝拍立淘按图搜索API接口是淘宝开放平台提供的一项基于图像识别技术的服务&#xff0c;允许开发者通过上传商品图片&#xff0c;获取与图片相似或相同的商品列表。该接口广泛应用于…

每天学一个 Linux 命令(8):ls

大家好,欢迎来到《每天掌握一个Linux命令》系列。在这个系列中,我们将逐步学习并熟练掌握Linux命令,今天,我们要学习的命令是ls。 01 什么是ls命令 在Linux系统中,ls命令是“list”的缩写,其英文全称为“list directory contents”,即“列出目录内容”。该命令非常实用…

00.【Linux系统编程】 Linux初识(云服务器设置CentOS并使用、Xshell链接云服务器)

目录 一、华为云服务器免费体验申请 二、Xshell远程链接创建好的华为云服务器 2.1 下载Xshell 2.2 Xshell远程连接华为云服务器 一、华为云服务器免费体验申请 华为云官网 1. 进入华为云官网&#xff0c;最上面一栏点活动&#xff0c;并进入免费体验中心。 2. 找到含有“…

arm非对齐访问编译器选项

gcc编译选项&#xff1a; -munaligned-access gcc编译选项&#xff1a; -mno-unaligned-access Enables (or disables) reading and writing of 16- and 32- bit values from addresses that are not 16- or 32- bit aligned. By default unaligned access is disabled for…

jmeter线程组高并发(详细讲解)

在 JMeter 中&#xff0c;线程组是测试计划的核心组件&#xff0c;用于定义虚拟用户&#xff08;线程&#xff09;的行为。线程组的属性决定了测试的并发用户数、加载速度、运行时间等。以下是线程组属性的详细讲解&#xff1a; 1. 名称&#xff08;Name&#xff09; 定义&…

vs2022中使用spdlog、C++日志

spdlog::set_level(spdlog::level::info); // 只显示info及比info高级的信息&#xff0c;trace 和 debug 不显示 参考&#xff1a;Windows10中使用VS2022和Cmake编译构建C开源日志库-spdlog-腾讯云开发者社区-腾讯云 spdlog C日志管理 | 快速上手教程 - 知乎 1.按照上述步骤…

SOME/IP-SD -- 协议英文原文讲解10

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.5 Non…

STM32 ADC转换完成回调函数详解 HAL_ADC_ConvCpltCallback与HAL_ADC_ConvHalfCpltCallback

HAL_ADC_ConvCpltCallback 和 HAL_ADC_ConvHalfCpltCallback 是 STM32 HAL 库中用于处理 ADC&#xff08;模数转换器&#xff09;转换完成事件的回调函数。它们分别在 ADC 转换完成和转换完成一半时被调用。以下是它们的详细说明&#xff1a; 1. HAL_ADC_ConvCpltCallback 功能…

Android OpenGLES 360全景图片渲染(球体内部)

概述 360度全景图是一种虚拟现实技术&#xff0c;它通过对现实场景进行多角度拍摄后&#xff0c;利用计算机软件将这些照片拼接成一个完整的全景图像。这种技术能够让观看者在虚拟环境中以交互的方式查看整个周围环境&#xff0c;就好像他们真的站在那个位置一样。在Android设备…

代码随想录算法训练营第三十二天 | 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯

509. 斐波那契数 题目链接&#xff1a;509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;手把手带你入门动态规划 | LeetCode&#xff1a;509.斐波那契数_哔哩哔哩_bilibili 思路&#xff1a;输入&#xff1a;…

拼多多 anti-token unidbg 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 版本7.3-7.4 都试过加密没什…

【工具】BioPred一个用于精准医疗中生物标志物分析的 R 软件包

介绍 R 语言包 BioPred 提供了一系列用于精准医疗中的亚组分析和生物标志物分析的工具。它借助极端梯度提升&#xff08;XGBoost&#xff09;算法&#xff0c;并结合倾向得分加权和 A 学习方法&#xff0c;帮助优化个体化治疗规则&#xff0c;从而简化亚组识别过程。BioPred 还…

横扫SQL面试——时间序列分组与合并(会话划分)问题

横扫SQL面试题 &#x1f4cc; 时间序列分组与合并问题 &#x1f4da; 横扫SQL面试——时间序列分组与合并解析 &#x1f31f; 核心问题类型 时间序列分组&#xff08;Sessionization&#xff09; 处理具有时间维度的连续数据流&#xff0c;根据特定规则&#xff08;如时间间隔…

PCB钻孔之多边形孔分析

问题分析 在钻孔过程中&#xff0c;钻头的运动可以分为两部分&#xff1a; 公转&#xff1a;钻头的轴线绕理想轴线&#xff08;钻孔中心线&#xff09;做圆周运动。自转&#xff1a;钻头绕自身轴线做旋转运动。 由于公转和自转的叠加&#xff0c;钻尖的运动轨迹会形成复杂的…

Android源码之App启动

目录 App启动概述 App启动过程 App启动过程图 源码概述 跨进程启动 进程内启动 下面以应用桌面Launcher启动App的MainActivity来举例&#xff1a; App启动概述 首先&#xff0c;MainActivity是由Launcher组件来启动的&#xff0c;而Launcher又是通过Activity管理服务Act…

指纹浏览器技术解析:如何实现多账号安全运营与隐私保护

浏览器指纹的挑战与需求 在数字化运营场景中&#xff0c;浏览器指纹技术被广泛用于追踪用户行为。通过采集设备硬件参数&#xff08;如屏幕分辨率、操作系统&#xff09;、软件配置&#xff08;如字体、插件&#xff09;及网络特征&#xff08;如IP地址、时区&#xff09;&…

生活电子常识——cmd不能使用anaconda的python环境,导致输入python打开应用商店

前言 电脑已经安装了anaconda,从自带的Anaconda Prompt (Anaconda3)中是可以识别python环境的&#xff0c;然而切换到cmd时&#xff0c;突然发现cmd中无法识别anaconda的python环境&#xff0c;竟然打开了应用商店让我安装Python&#xff0c;这当然是不对的。 解决 这是因为…