JS数组特征
- js数组不是典型的数组,是用对象模拟的数组
- 典型的数组特征:
- 存储元素的数据类型相同
- 使用连续的内存
- 通过数字下标获取元素
- js数组特征:
- 存储元素类型可以不同
- 内存不一定连续,对象随机存储
- 不是通过数字下标而是通过字符串下标获取元素,所以数组可以有任何key,比如
let arr = [1,2,3];
arr['xx'] = 11;
创建数组
- 新建
let arr = [1,2,3];
let arr = new Array(1,2,3); // 元素
let arr = new Array(3); // 长度
- 字符串 -> 数组
let arr = '1,2,3'.split(','); // ["1", "2", "3"]
let arr = '123'.split(''); // ["1", "2", "3"]
let arr = Array.from(123); // ["1", "2", "3"]
- 数组 -> 字符串
let arr = [1, 2, 3];
let str = arr.join('-'); // "1-2-3", 默认以","连接
arr.toString(); // "1,2,3"
伪数组
- 伪数组的原型链中没有数组的原型,没有数组的共有属性
let arr = document.querySelectorAll('div'); // 返回的是伪数组
- 合并两个数组,得到新数组,不改变原数组
let arr1 = [1,1];
let arr2 = [2,2];
arr1.concat(arr2); // [1, 1, 2, 2]
- 截取数组的一部分,得到新数组,不改变原数组
let arr = [1,2,3,4];
arr.slice(1); // [2, 3, 4]
arr.slice(0); // [1,2,3,4], 用于复制一个数组,js只提供浅拷贝
arr.slice(); // [1,2,3,4]
增删改查
增
从头部增加
arr.unshift(item1, item2) // 修改 arr, 返回新长度
从尾部增加
arr.push(item1, item2) // 修改 arr, 返回新长度
从中间增加
arr.splice(index, 0, 'x'); // 在 Index 处插入 'x'
arr.splice(index, 0, 'x', 'y'); // 在 Index 处插入 'x', 'y'
删
从头部删除
arr.shift() // arr被修改,并返回被删元素
从尾部删除
arr.pop() // arr被修改,并返回被删元素
从中间中间元素
// splice 会返回被删数组
arr.splice(index, 1) // 删除 index 处的一个元素
arr.splice(index, 1, 'x') // 删除 index 处的一个元素并在删除处添加 'x'
arr.splice(index, 1, 'x', 'y') // 删除 index 处的一个元素并在删除处添加 'x', 'y'
delete 删除
// 对象一样的方法
// 数组长度不变
let arr = ['a', 'b', '3'];
delete arr['0'];
arr // [empty, "b", "3"]
直接改length, 最好不用
let arr = [1, 2, 3, 4];
arr.length = 1;
arr // [1]
改
直接改
let arr = [1, 2, 3, 4];
arr[0] = 'a';
反转顺序 ```javascript arr.reverse(); // 改变原数组
// 反转字符串 let s = ‘abc’; s.split(‘’).reverse().join(‘’); // “cba”
- 使用 sort 自定义排序
```javascript
// 默认从小到大排序
let arr = [5, 4, 3, 2, 1];
arr.sort(); // [1, 2, 3, 4, 5]
// 自定义排序 arr.sort(fn)
// fun 返回:正数, 0, 负数
arr.sort((a, b) => {
return b-a;
}) // [5, 4, 3, 2, 1]
// 打乱原数组顺序
arr.sort(function(a, b){
return 0.5 - Math.random();
});
- 查
- 查看单个属性 ```javascript let arr = [‘a’, ‘b’, ‘c’]; arr[0]
// 索引越界 arr[100] === undefined // true arr[-1] === undefined // true
// 查找某个元素是否在数组里 arr.indexOf(item); // 存在返回索引,不存在返回 -1
// 使用条件查找元素 arr.find(item => item%2 === 0); // 返回第一个偶数
// 使用条件查找元素的索引 arr.findIndex(item => item%2 === 0); // 返回第一个偶数的索引
<a name="RPMRP"></a>
### 遍历数组
- for 循环遍历数组
```javascript
let arr = [1, 2, 3];
arr.x = 'xxx';
// 查看所有属性名
Object.keys(arr); // ["0", "1", "2", "3", "4", "x"]
// for循环遍历
for(let i = 0; i < arr.length; i++){
console.log(`${i}: ${arr[i]}`); // 由于属性值 'x' 的下标不是数字,不会改变 arr.length,所以不会被打印出来
}
// 0: 1
// 1: 2
// 2: 3
- 用 forEach 遍历数组(推荐)
let arr = [1, 2, 3];
arr.forEach(function(item, index){
console.log(`${index}: ${item}`)
});
// 0: 1
// 1: 2
// 2: 3
手动实现 forEach
let arr = ['a', 'b', 'c'];
function forEach(array, fn) {
for (let i = 0; i < array.length; i++) {
fn(array[i], i, array);
}
}
forEach(arr, function(item, index, array){
console.log(item, index, array);
})
// a 0 ["a", "b", "c"]
// b 1 ["a", "b", "c"]
// c 2 ["a", "b", "c"]
数组变换
- map:n 变 n
将数组中每个值传入函数中,返回处理后的值
// 题1:将数字转换为星期
let arr = [0,1,2,2,3,3,3,4,4,4,4,6];
let arr2 = arr.map((item)=>{
let num2week = {'0': '周日', '1': '周一', '2': '周二', '3': '周三', '4': '周四', '5': '周五', '6': '周六'};
return num2week[item];
});
console.log(arr2); // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']
- filter: n 变 m (m < n)
将数组中每个值传入函数中,返回值为布尔值,true则保留,false则去掉
// 题2:输出大于60的数
let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
let scores2 = scores.filter((item) => {
return item > 60;
})
console.log(scores2) // [95,91,82,72,85,67,66, 91]
- reduce:n 变 1
// 题3:算出所有奇数之和
let numbers = [95,91,59,55,42,82,72,85,67,66,55,91]
let sum = numbers.reduce((sum, n)=>{
return sum + (n % 2 === 0 ? 0:n);
},0) // 0 为 sum的初始值
console.log(sum) // 奇数之和:598