javascript技巧

关注公众号 jb51net

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

从零基础到工程级实战解析JavaScript数组的终极指南

作者:Yira

在 JavaScript 的世界里,数组(Array)是一种高度灵活,功能强大,可扩展的数据结构,本文将带你彻底搞懂 JavaScript 数组以及在现代开发中的最佳实践

在 JavaScript 的世界里,数组(Array)  不仅仅是一个“装东西的盒子”,它是一种高度灵活、功能强大、可扩展的数据结构。无论是处理用户列表、管理购物车商品、解析 API 返回数据,还是实现复杂算法,都离不开数组。

本文将带你彻底搞懂 JavaScript 数组——包括它的本质、创建方式、核心特性、常用方法、性能注意事项、常见陷阱,以及在现代开发中的最佳实践。

一、JavaScript 中到底有没有“真正的”数组?

这是一个常被误解的问题。

答案:有,但和传统语言不同

在 C/C++、Java 等静态语言中,数组是:

而 JavaScript 的数组是:

技术细节:在 V8 引擎(Chrome/Node.js 使用)中,JavaScript 数组会根据内容自动选择两种内部表示:

因此,虽然 JS 数组“看起来像”传统数组,但其底层更接近“带数字键的对象”。

二、如何创建数组?四种方式详解

1.数组字面量(推荐)

const arr = [1, 'hello', true];

2.Array 构造函数(谨慎使用)

// 传入多个参数 → 创建包含这些元素的数组
const a1 = new Array(1, 2, 3); // [1, 2, 3]

// 传入单个数字 → 创建指定长度的空数组(⚠️陷阱!)
const a2 = new Array(5); // [empty × 5],不是 [5]!

危险点:new Array(3) 不等于 [3],前者是长度为 3 的空数组,后者是包含数字 3 的数组。

3.Array.of()(安全替代构造函数)

Array.of(5);        // [5]
Array.of(1, 2, 3);  // [1, 2, 3]

4.Array.from()(从类数组或可迭代对象创建)

// 从字符串
Array.from('abc'); // ['a', 'b', 'c']

// 从 NodeList
Array.from(document.querySelectorAll('div'));

// 从 Set
Array.from(new Set([1, 2, 2])); // [1, 2]

// 带映射函数
Array.from({ length: 3 }, (_, i) => i * 2); // [0, 2, 4]

三、数组的核心属性与判断方法

1.length属性

let arr = [];
arr[99] = 'last';
console.log(arr.length); // 100
console.log(Object.keys(arr).length); // 1(实际只有1个元素)

2. 如何判断一个变量是数组

// ❌ 错误方式
typeof []; // "object"

// ✅ 正确方式
Array.isArray([]); // true

// 兼容旧浏览器(不推荐)
Object.prototype.toString.call([]) === '[object Array]';

四、数组操作全景图(按功能分类)

A.增删改查(CRUD)

操作方法是否修改原数组返回值
末尾添加push()✅ 是新长度
开头添加unshift()✅ 是新长度
末尾删除pop()✅ 是被删元素
开头删除shift()✅ 是被删元素
任意位置增删splice(start, deleteCount, ...items)✅ 是被删元素组成的数组
替换/插入(不修改原数组)toSpliced()(ES2023)❌ 否新数组

示例:

const arr = [1, 2, 3];
arr.splice(1, 1, 'a', 'b'); // 从索引1删1个,插入'a','b'
console.log(arr); // [1, 'a', 'b', 3]

B.遍历与转换(函数式编程核心)

方法用途是否修改原数组返回值
forEach()遍历执行副作用undefined
map()映射新值新数组
filter()过滤符合条件的新数组
reduce()聚合计算(求和、扁平化等)累积值
find() / findIndex()查找第一个匹配项元素 / 索引
some() / every()判断是否存在 / 是否全部满足布尔值

关键区别:

C.搜索与判断

const nums = [10, 20, 30];

nums.indexOf(20);      // 1(找不到返回 -1)
nums.lastIndexOf(20);  // 1(从后往前找)

nums.includes(20);     // true(ES2016,更语义化)

// 支持 NaN
[NaN].includes(NaN);   // true
[NaN].indexOf(NaN);    // -1(因 NaN !== NaN)

D.连接、切片与复制

方法说明
concat()合并多个数组或值,返回新数组
slice(start, end)截取子数组(end 不包含),返回新数组
[...arr]展开运算符,浅拷贝数组
Array.from(arr)浅拷贝(也可用于类数组)

注意:以上均为浅拷贝!嵌套对象仍共享引用。

E.排序与反转

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

letters.sort();        // ['a', 'b', 'c'](✅ 修改原数组!)
letters.reverse();     // ['c', 'b', 'a'](✅ 修改原数组!)

// 数字排序需传比较函数
[10, 2, 30].sort((a, b) => a - b); // [2, 10, 30]

重要:sort() 和 reverse() 会直接修改原数组,若需保留原数据,先复制再操作。

五、高级技巧与工程实践

1.不可变性(Immutability)原则

在 React、Redux 等现代框架中,强调“不直接修改状态”。因此应避免 pushsplice 等方法,改用:

// ❌ 不推荐(修改原数组)
state.items.push(newItem);

// ✅ 推荐(返回新数组)
const newItems = [...state.items, newItem];

2.扁平化嵌套数组

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

nested.flat();        // [1, 2, [3, [4]]]
nested.flat(2);       // [1, 2, 3, [4]]
nested.flat(Infinity); // [1, 2, 3, 4](彻底扁平化)

// 或用 reduce 递归实现

3.去重(Deduplication)

// 基本类型去重
const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]

// 对象数组去重(按 id)
const users = [{id:1}, {id:2}, {id:1}];
const seen = new Set();
const uniqueUsers = users.filter(user => {
  if (seen.has(user.id)) return false;
  seen.add(user.id);
  return true;
});

4.性能建议

六、常见误区与陷阱

误区 1:[] == false所以数组是假值?

Boolean([]); // true!空数组是真值
if ([]) console.log('yes'); // 会执行

原因:所有对象(包括空数组、空对象)在布尔上下文中都是 true

误区 2:arr.length = 0会清空数组?

let a = [1, 2, 3];
let b = a;
a.length = 0;
console.log(b); // [] —— 因为 a 和 b 指向同一引用!

误区 3:delete arr[1]会缩短数组?

let arr = [1, 2, 3];
delete arr[1];
console.log(arr);        // [1, empty, 3]
console.log(arr.length); // 3(长度不变!)

正确做法:用 splice(1, 1) 删除并收缩数组。

七、总结:数组使用心法

场景推荐方法
添加元素push(末尾)、... + concat(不可变)
删除元素filter(不可变)、splice(可变)
遍历处理map(转换)、forEach(副作用)
条件筛选filter、find、some
聚合计算reduce
安全复制[...arr]、Array.from(arr)
判断类型Array.isArray()

八、动手练习(巩固理解)

提示:多用 mapreduceSet 组合解决!

结语

JavaScript 数组看似简单,实则博大精深。它既是新手入门的第一道关卡,也是高手优化性能的关键战场。理解其本质、掌握其方法、避开其陷阱,你就能在任何 JavaScript 项目中游刃有余。

以上就是从零基础到工程级实战解析JavaScript数组的终极指南的详细内容,更多关于JavaScript数组的资料请关注脚本之家其它相关文章!

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