JavaScript数组完全指南
JavaScript数组是完全指南
数组(Array)属于JavaScript的内置对象类型,与普通对象的功能相似,都可以用于存储多个值。主要区别在于:普通对象使用字符串作为属性名,而数组使用数字索引来访问元素。索引是从0开始的整数。
数组在存储性能方面优于普通对象。实际开发中,数组常用于存储列表类型的数据,使用频率非常高。
数组创建方法
JavaScript提供了多种创建数组的方式。
字面量方式
let emptyArray = [];
let initializedArray = [1, 2, 3];
构造函数方式
let arr = new Array(参数);
let arr = Array(参数);
构造函数的行为如下:参数为空时创建空数组;参数为单个数值时表示数组长度;多个参数则表示数组的初始元素。
let numbers = [1, 2, 3];
let empty = new Array();
let sized = new Array(5);
let mixed = new Array(1, "world", {"name": "lisa", "age": 18}, [4, 7]);
console.log('numbers = ' + JSON.stringify(numbers));
console.log('empty = ' + JSON.stringify(empty));
console.log('sized = ' + JSON.stringify(sized));
console.log('mixed = ' + JSON.stringify(mixed));
数组可以存储任意类型的数据,包括字符串、数字、布尔值、对象和其他数组。
数组基本操作
索引(下标)用于访问数组元素,代表元素在数组中的位置,从0开始计算。
添加元素
let buffer = new Array(5);
buffer[1] = 100;
buffer[3] = 0;
buffer[6] = 2;
console.log('buffer = ' + JSON.stringify(buffer));
当索引超过数组当前长度时,数组会自动扩展容量。
获取元素
访问不存在的索引不会报错,而是返回undefined:
const collection = [21, 22, 23];
console.log(collection[0]);
console.log(collection[5]);
获取数组长度
使用length属性获取数组元素个数:
const collection = [21, 22, 23];
console.log(collection.length);
对于连续数组,length返回元素个数;对于非连续的稀疏数组,length会大于实际元素个数。建议避免创建非连续的数组。
修改数组长度
通过修改length属性可以调整数组大小:
const source = [11, 12, 13];
const target = [21, 22, 23];
source.length = 1;
console.log(JSON.stringify(source));
target.length = 5;
console.log(JSON.stringify(target));
- 增大length:多出的位置填充null
- 减小length:从末尾删除多余元素
遍历数组
遍历数组即依次访问每个元素,最常用的是for循环:
let data = [1, "alice", 12, {"name": "lisa", "age": 18}, [33, 44]];
for (let i = 0; i < data.length; i++) {
console.log(data[i]);
}
JavaScript数组的独特之处:
- 访问不存在索引返回undefined而非报错
- 数组可自动扩容,其他语言通常固定长度
- 可存储不同类型元素,其他语言通常要求类型一致
- 存储空间不一定连续,采用哈希映射方式分配空间
各大浏览器对此进行了优化:存储同类型数据时尽量分配连续空间,存储不同类型则可能不连续。
数组解构赋值
ES6新增的解构赋值简化了元素赋值操作。
ES5写法:
const source = [1, 2, [3, 4]];
let a = source[0];
let b = source[1];
let c = source[2];
ES6解构写法:
let [a, b, c] = [1, 2, [3, 4]];
console.log(a);
console.log(b);
console.log(c);
注意事项:
- 左右两边格式必须完全一致才能完整解构
- 元素个数可以不同
可以设置默认值:
let [a, b = 3, c = 4] = [1, 2];
console.log(a);
console.log(b);
console.log(c);
使用扩展运算符打包剩余数据:
let [first, ...rest] = [1, 2, 3];
console.log(first);
console.log(rest);
数组常用方法
类型判断与转换
| 方法 | 功能 | 说明 |
|---|---|---|
| Array.isArray() | 判断是否为数组 | |
| toString() | 转换为字符串 | 不改变原数组 |
| join() | 转换为字符串 | 可指定分隔符,不改变原数组 |
| split() | 字符串分割为数组 | 字符串方法 |
| Array.from() | 伪数组转真数组 | |
| Array.of() | 创建数组 | 将多个值转为数组 |
let sample = [1, "bob", {"name": "mike", "age": 12}, [22, 55]];
console.log(Array.isArray(sample));
console.log(sample.toString());
console.log(sample.join(","));
伪数组具有length属性但没有数组原型方法,无法使用push、pop等操作。可通过Array.from()转换为真数组。
元素增删
| 方法 | 功能 | 返回值 | 原数组 |
|---|---|---|---|
| push() | 末尾添加元素 | 新长度 | 改变 |
| pop() | 删除末尾元素 | 被删除元素 | 改变 |
| unshift() | 开头添加元素 | 新长度 | 改变 |
| shift() | 删除开头元素 | 被删除元素 | 改变 |
| splice() | 删除/替换元素 | 被删除元素组成的新数组 | 改变 |
| concat() | 合并数组 | 新数组 | 不变 |
| fill() | 填充数组 | 新数组 | 改变 |
let sample = [1, "bob", {"name": "mike", "age": 12}, [22, 55]];
console.log(sample.push(100));
console.log(sample);
console.log(sample.pop());
console.log(sample);
console.log(sample.unshift(23, [34, 56]));
console.log(sample);
console.log(sample.shift());
console.log(sample);
splice()详细用法
let items = [1, "bob", {"name": "mike", "age": 12}, [22, 55]];
let result1 = items.splice(1);
console.log(items);
console.log(result1);
items = [1, "bob", {"name": "mike", "age": 12}, [22, 55]];
let result2 = items.splice(1, 2);
console.log(items);
console.log(result2);
items = [1, "bob", {"name": "mike", "age": 12}, [22, 55]];
let result3 = items.splice(1, 2, "replacement", "newItem");
console.log(items);
console.log(result3);
concat()与slice()
concat()用于数组合并:
const arr1 = [1, 2, 3];
const combined = ['a', 'b', 'c', ...arr1];
slice()提取元素:
let subArray = originalArray.slice(startIndex, endIndex);
fill()填充数组
let filled = [1, 2, 3].fill(0);
let partialFill = [1, 2, 3, 4].fill(0, 1, 3);
数组排序
| 方法 | 功能 | 原数组 |
|---|---|---|
| reverse() | 反转数组 | 改变 |
| sort() | 排序 | 改变 |
let values = [1, 3, 2, 5, 6];
values.reverse();
console.log(values);
sort()默认按Unicode编码排序,可能产生意外结果:
let values = [1, 3, 12, 5, 6];
values.sort();
console.log(values);
自定义排序需要传入回调函数:
values.sort((a, b) => a - b);
console.log(values);
let objects = [
{'age': 2, 'score': 34},
{'age': 12, 'score': 24},
{'age': 5, 'score': 63},
{'age': 21, 'score': 87}
];
objects.sort((a, b) => a.age - b.age);
console.log(objects);
回调函数返回值规则:返回正值交换位置,返回负值不交换,返回0视为相等。
查找元素
| 方法 | 功能 |
|---|---|
| indexOf() | 从前往后查找索引 |
| lastIndexOf() | 从后往前查找索引 |
| includes() | 判断是否包含 |
| find() | 查找第一个满足条件的元素 |
| findIndex() | 查找第一个满足条件的索引 |
| every() | 检查是否所有元素都满足条件 |
| some() | 检查是否存在满足条件的元素 |
let position = array.indexOf(target, startIndex);
let lastPosition = array.lastIndexOf(target);
let exists = array.includes(item, position);
let found = array.find((item, index, arr) => {
return typeof item === 'object';
});
let foundIndex = array.findIndex((item, index) => {
return typeof item === 'object';
});
every()要求所有元素返回true才为true,some()只要有一个返回true就为true:
const numbers = [23, "bob", {"name": "mike"}, [23, 56], "22"];
let allPass = numbers.every(item => item.length > 2);
let somePass = numbers.some(item => item.length > 2);
数组遍历
| 方法 | 说明 |
|---|---|
| for循环 | 传统遍历方式 |
| forEach() | 遍历数组,无返回值 |
| for of | ES6语法遍历值 |
| map() | 加工每个元素,返回新数组 |
| filter() | 过滤元素,返回新数组 |
| reduce() | 累计处理 |
let data = [23, "bob", {"name": "mike"}, [23, 56], "22"];
for (let i = 0; i < data.length; i++) {
console.log(data[i]);
}
data.forEach((item, index) => {
console.log(item);
});
for (let value of data) {
console.log(value);
}
map()映射加工
const nums = [1, 3, 6, 2, 5, 6];
const processed = nums.map(item => item * 2);
console.log(processed);
filter()过滤筛选
const nums = [1, 3, 6, 2, 5, 6];
const filtered = nums.filter(item => item > 4);
console.log(filtered);
reduce()累计计算
arr.reduce((prev, current, index, array) => {
return newValue;
}, initialValue);
参数说明:
- prev:上次回调返回值
- current:当前处理元素
- index:当前索引
- array:原数组
- initialValue:初始值
let nums = [1, 2, 3, 4, 5, 6];
nums.reduce((prev, item) => {
console.log(prev);
console.log(item);
console.log('---');
return item * 2;
}, 0);
reduce()功能强大,可替代多数数组方法,熟练掌握能显著提升编码能力。