数组:
- 最简单的内存数据结构
- 存储一系列同一种数据类型的值
- 注意: 虽然JavaScript中,可以在数组里保存不同类型的值,但是要避免此类做法
1. 创建和初始化数组
- 可以使用new关键字声明、创建和初始化一个数组
// 使用new关键字简单声明并创建一个数组
let arr = new Array();
// 创建一个指定长度的数组
let arr1 = new Array(3);
// 直接将数组元素传递给他的构造器
let arr2 = new Array('hello', 'world');
- 使用[]的形式创建数组
let arr = [];
// 使用一些元素初始化数组
let arr1 = ['hello', 'world'];
- 通过数组的
length
属性可以知道数组的长度
2. 访问数组和迭代数组
- 访问数组中特定元素的位置可以使用中括号传递数组的位置
- 输出数组内所有元素
let arr = [1, 2, 3, 4, 5];
for(let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
3. 添加元素
假设有以下数组:
let arr = [1, 2, 3, ..., 9];
3.1 在数组末尾插入元素
- 可以直接把值赋值给数组中最后一个空位上的元素
// 插入数值10
arr[arr.length] = 10;
在JavaScript中,数组是一个可修改长度的对象。添加元素后会动态增长。
push方法
:直接将元素添加到数组末尾
// 插入数值11,12,13
arr.push(11);
arr.push(12, 13);
数组输出结果为1到13。
3.2 在数组开头插入元素
- 先腾出数组里第一个元素的位置
- 把所有元素向右移动一位
- 把想要的值赋值给第一个位置
Arr.prototype.insertFirstPosition = function(value) {
for(let i = this.length; i > 0; i--) {
this[i] = this[i - 1];
}
this[0] = value;
};
// 插入数值-1
arr.insertFirstPosition(-1);
unshift方法
:直接把数值插到数组的开头
// 此方法逻辑与insertFirstPosition是一样的,插入-2,-3,-4
arr.unshift(-2);
arr.unshift(-4, -3);
数组输出结果为-4到13。
4. 删除元素
4.1 在数组末尾删除元素
pop方法
:删除数组里最靠后的元素
arr.pop();
通过使用
push
和pop
方法可以用来模拟栈。
数组输出结果为-4到12。
4.2 在数组开头删除元素
shift方法
:删除数组的第一个元素
arr.shift();
数组输出结果为-3到12。
通过使用
shift
和unshift
方法可以模拟基本的队列数据结构。
5. 在任意位置添加或删除元素
splice(想要删除或插入的元素的索引值, 删除元素的个数, 添加到数组里的值1, 添加到数组里的值2, ...)
- 使用
splice方法
,通过指定位置/索引,删除相应位置上指定数量的元素
// 删除从索引5开始的3个元素
arr.splice(5, 3);
此时arr[5]、arr[6]、arr[7]即2、3、4被删除。
- 将2、3、4插入被删除的位置上
// 在索引值为5的地方,删除0个元素,插入2、3、4
arr.splice(5, 0, 2, 3, 4);
上述两行代码相当于:
// 先从索引5的位置开始删除3个元素,再从索引5的位置开始添加2,3,4
arr.splice(5, 3, 2, 3, 4);
6. 迭代二维数组的元素
function printMatrix(myMatrix) {
for(let i = 0; i < myMatrix.length; i++) {
for(let j = 0; j < myMatrix[i].length; j++) {
console.log(myMatrix[i][j]);
}
}
}
多维数组同理嵌套for循环
7. JavaScript的数组方法
7.1 concat
数组合并
连接2个或多个数组,并返回结果。
const a = 0;
const b = [1, 2, 3];
const c = [-1, -2, -3];
let arr = c.concat(a, b);
arr // -1, -2, -3, 0, 1, 2, 3
- concat方法可以向数组传递数组、对象或元素
- 数组会按照该方法传入的参数顺序连接指定数组
7.2 迭代器函数
JavaScript内置了许多可以迭代数组元素的方法。
假设存在一个数值为1-15的数组,偶数返回true,奇数返回false:
const isEven(x) = x => x % 2 === 0;
let arr = [1, 2, ..., 15];
return (x % 2 === 0) ? true : false; 可以简化为:return (x % 2 === 0);
1. every方法
对数组中的每个元素运行给定函数,如果该函数对每个元素都返回true,则返回true。
// every方法会迭代数组中的每个元素,直到返回false
arr.every(isEven); // false
解释:
数组arr被迭代的第一个元素是1,不是偶数,因此isEven函数返回false,然后every执行结束。
2. some方法
对数组中的每个元素运行给定函数,返回该函数会返回true的元素组成的数组。
// some方法会迭代数组中的每个元素,直到返回true
arr.some(isEven); // true
解释:
数组arr的第一个元素是1,isEven返回false;第二个被迭代的元素是2,isEven返回true,迭代结束。
3. forEach方法
迭代整个数组,和使用for循环的结果相同,该方法没有返回值。
arr.forEach(x => console.log(x % 2 === 0));
4. map方法
和filter方法
- map方法:
返回每次函数调用的结果组成的数组。
const map1 = arr.map(isEven);
- filter方法
返回的新数组由使函数返回true的元素组成。
const filter1 = arr.filter(isEven);
5. 其他常用方法
方法 | 描述 |
join | 将所有的数组元素连接成一个字符串 |
indexOf | 返回第一个与给定参数相等的数组元素的索引,没有找到返回-1 |
lastIndexOf | 返回在数组中搜索到的与给定参数相等的元素的索引里的最大值 |
slice | 传入索引值,将数组里对应索引范围内的元素作为新数组返回 |
sort | 按照字母顺序对数组排序,支持传入指定排序方法的函数作为参数 |
toString | 将数组作为字符串返回 |
valueOf | 类似toString,将数组作为字符串返回 |
7.3 ES2015和ES2016新增的数组方法
1. 使用for...of
循环迭代
for (const n of arr) {
console.log(n % 2 === 0 ? 'even' : 'odd');
}
2. @@iterator
对象
返回一个包含数组键值对的对象,可以通过同步调用得到数组元素的键值对。
需要通过Symbol.iterator
来访问。
let iterator = arr[Symbol.iterator]();
// 不断调用迭代器的next方法,就能一次得到数组中的值
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
console.log(iterator.next().value); // 4
...
console.log(iterator.next().value); // 15
// 当数组中的所有值都迭代完之后会返回undefined
console.log(iterator.next().value); // undefined
3. entries
、keys
和values
方法
entries
方法返回包含数组所有键值对的@@iterator
// 得到键值对的迭代器
let entries1 = arr.entries()
console.log(entries1.next().value); //[0, 1] 位置0的值为1
console.log(entries1.next().value); //[1, 2] 位置1的值为2
console.log(entries1.next().value);
console.log(entries1.next().value);
使用集合、字典、散列表等数据结构时,能够取出键值对是很有用的。
keys
方法返回包含数组所有索引的@@iterator
// 得到数组索引的迭代器
let keys1 = arr.keys();
console.log(keys1.next());
console.log(keys1.next());
console.log(keys1.next());
console.log(keys1.next());
可迭代的值 | 返回结果 |
有 | {value: 值, done: false} |
无 | {value: undefined, done: true} |
// 得到数组索引的迭代器
let keys1 = arr.keys()
console.log(keys1.next().value); // 0
console.log(keys1.next().value); // 1
console.log(keys1.next().value); // 2
console.log(keys1.next().value); // 3
values
返回包含数组中所有值的@@iterator
// 得到数组中所有值的迭代器
let values1 = arr.values();
console.log(values1.next());
console.log(values1.next());
console.log(values1.next());
console.log(values1.next());
4. from
方法
Array.from
可以根据已有数组创建一个新数组。
- 复制数组:
let arr1 = Array.from(arr);
console.log(arr1);
- 传入一个用来过滤值的函数:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const isEven = x => x % 2 === 0;
let arr2 = Array.from(arr, isEven);
console.log(arr2);
5. Array.of
方法
根据传入的参数创建一个新数组。
let arr1 = Array.of(1);
let arr2 = Array.of(2, 3, 4, 5);
相当于:
let arr1 = [1];
let arr2 = [2, 3, 4, 5];
- 使用该方法复制数组:
// ... 展开运算符,把arr2里的值展开为参数
let copyArr2 = Array.of(...arr2);
6. fill
方法
用静态值填充数组。
let copyArr2 = Array.of(...arr2);
copyArr2数组的长度为4。
- 将copyArr2数组所有位置上的值都变成0:
copyArr2.fill(0); // [0, 0, 0, 0]
- 指定开始位置的索引:
// 数组从索引1开始的位置的数值都为2
copyArr2.fill(2, 1); // [0, 2, 2, 2]
- 指定结束填充的索引:
// 把1填充到索引为2到3的位置
copyArr2.fill(1, 2, 3); // [0, 2, 3, 3]
- 创建数组并初始化时使用fill(推荐):
// 创建了一个length为6的数组,所有值都初始化为1
let newArr = Array(6).fill(1);
7. copyWithin
方法
复制数组中一系列元素到同一数组指定的起始位置。
let arr = [1, 2, 3, 4, 5, 6];
// 将4,5,6复制到数组前三个位置
arr.copyWithin(0, 3); // [4, 5, 6, 4, 5, 6]
let arr = [1, 2, 3, 4, 5, 6];
// 将4,5复制到数组1, 2的位置
arr.copyWithin(1, 3, 5); // [1, 4, 5, 4, 5, 6]
8. 排序元素
假设存在arr数组:
let arr = [1, 2, 3, ..., 15];
- 使用
reversr
方法使数组反序输出:
arr.reverse();
- 使用
sort
方法排序:
arr.sort();
sort方法在进行数组排序时,会把元素默认成字符串进行比较。
解决方法:传入自己写的比较函数。
// 当b > a时,返回负数
// 当b < a时,返回正数
// 当b = a时,返回0
arr.sort((a, b) => a - b);
function compare(a, b) {
if(a < b) {
return -1;
}
if(a > b) {
return 1;
}
return 0;
}
arr.sort(compare);
- 字符串排序
假设有以下数组:
let arr = ['Aaa', 'aaa', 'Bbb', 'bbb'];
- 使用
sort
方法排序:
arr.sort();
JavaScript在做字符比较时是根据字符对应的ASCII值来比较的
解决方法:传入一个忽略大小写的比较函数。
arr.sort((a, b) => {
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
}
if (a.toLowerCase() > b.toLowerCase()) {
return 1;
}
return 0;
});
如果希望小写字母排在前面:
arr.sort((a, b) => a.localeCompare(b));
9. 搜索
1. indexOf
和lastIndexOf
let arr = [1, 2, 3, ..., 15];
// indexOf方法返回与参数匹配的第一个元素的索引
arr.indexOf(10); // 9
// lastIndexOf返回与参数匹配的最后一个元素的索引
arr.lastIndexOf(100); // -1 (因为100不在数组中)
2. find
和findIndex
find和findIndex接受一个回调函数,搜索一个满足回调函数条件。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
function mutipleOf13(element, index, array) {
return (element % 13 == 0);
}
// 返回第一个满足条件的值
console.log(arr.find(mutipleOf13)); // 13
// 返回第一个满足条件的索引
console.log(arr.findIndex(mutipleOf13)); // 12
find | findIndex |
返回第一个满足条件的值 | 返回第一个满足条件的索引 |
没有满足条件的值时返回undefined | 没有满足条件的值时返回-1 |
3. includes
方法
如果数组中存在某元素,includes方法返回true,否则返回false。
console.log(arr.includes(10)); // true
console.log(arr.includes(20)); // false
如果给数组传入一个起始索引,搜索会从索引指定位置开始。
console.log(arr.includes(4, 5)); // false,因为索引4后面的元素不包括5
10. 输出数组为字符串
-
toString
将所有元素输出为一个字符串
arr.toString();
-
join
用指定分隔符把元素隔开
arr.join('*');