1. 数组基本方法
- 数组定义、访问、长度 ```javascript let arr = [3, 4, ‘hello’, true] console.log(arr.length) // 4 console.log(arr[0]) // 3 console.log(arr[4]) // undefined console.log(arr[arr.length-1]) // true
// 清空数组 arr.length = 0 console.log(arr) // []
- **栈、队列方法**
- **pop()**
- **push()**
- **unshift()**
- **shift()**
```javascript
let arr = [0, 1, 2, 3]
// 尾部弹出元素
let val1 = arr.pop()
console.log(val1) // 3 返回弹出的元素
console.log(arr) // [0, 1, 2]
// 尾部增加元素
let val2 = arr.push(4)
console.log(val2) // 4 返回数组的元素个数
console.log(arr) // [0, 1, 2, 4]
// 头部添加元素
let val3 = arr.unshift(5)
console.log(val3) // 5 返回数组的元素个数
console.log(arr) // [5, 0, 1, 2, 4]
// 头部删除元素
let val4 = arr.shift()
console.log(val4) // 5 返回删除的元素
console.log(arr) // [0, 1, 2, 4]
- 任意位置添加、删除
- splice()
- 参数: 1.开始索引(插入在前);2.删除元素的个数;3.插入的新元素,可以写多个
- 返回:一个由删除元素组成的新数组 ```javascript let arr = [0, 1, 2, 3, 4, 5]
// 在下标为1的元素之前插入元素8和元素9 let val1 = arr.splice(1, 0, 8, 9) console.log(arr) // [0, 8, 9, 1, 2, 3, 4, 5] console.log(val1) // []
// 从下标为2的元素开始删除,一共删除两个元素 let val2 = arr.splice(2, 2) console.log(arr) // [0, 8, 2, 3, 4, 5] console.log(val2) // [9, 1]
// 将下标为0和下标为1的两个元素替换为6和7 let val3 = arr.splice(0, 2, 6, 7) console.log(arr) // [6, 7, 2, 3, 4, 5] console.log(val3) // [0, 8]
- 连接
- **concat()**
- 创建当前数组的副本,将接收的参数添加到副本的尾部,返回新数组
- **join()**
- 将数组转换成字符串
```javascript
let arr1 = [0, 1, 2]
// 连接数组
let arr2 = arr1.concat(3)
let arr3 = arr1.concat([4, 5])
console.log(arr2) // [0, 1, 2, 3]
console.log(arr3) // [0, 1, 2, 4, 5]
// 拷贝数组
let arr4 = arr1.concat()
console.log(arr4) // [0, 1, 2]
console.log(arr1 === arr4) // false
// 将数组转换成字符串
let str1 = arr1.join('')
console.log(str1) // "012"
let str2 = arr1.join('-')
console.log(str2) // "0-1-2"
/*
案例:实现按参数传递实现字符串重复次数
*/
let str1 = 'abc'
let str2 = repeatStr(str1, 5)
console.log(str2) // "aaaaabbbbbccccc"
// 实现字符串的重复
function repeatStr(str, count=2) {
let result = ''
for(let i = 0; i < str.length; i++) {
result += str[i].padStart(count, str[i])
}
return result
}
- 倒序、排序
- reverse()
- sort() ```javascript // reverse()可以实现数组逆序 let arr = [0, 1, 2, 3] let newArr = arr.reverse() console.log(newArr) // [3, 2, 1, 0] // reverse()会改变原数组 console.log(arr) // [3, 2, 1, 0]
```javascript
// 案例:实现字符串逆序
let str = '01234'
let newStr = reverseStr(str)
console.log(newStr) // "43210"
function reverseStr(str) {
return str.split('').reverse().join('')
}
let months = ['March', 'Jan', 'Feb', 'Dec']
months.sort()
console.log(months) // ["Dec", "Feb", "Jan", "March"]
let arr1 = [1, 30, 4, 21, 100]
arr1.sort()
// 结果并不是我们想要的
// 因为默认是会将元素转换为字符串,依次比较ASCII,值大的在前面
console.log(arr1) // [1, 100, 21, 30, 4]
arr1 = [1, 30, 4, 21, 100]
arr1.sort((a, b) => a-b) //从小到大 [1, 4, 21, 30, 100]
arr1 = [1, 30, 4, 21, 100]
arr1.sort((a, b) => b-a) //从大到小 [100, 30, 21, 4, 1]
// 排序元素不是数字的数组
months = ['March', 'Jan', 'Feb', 'Dec']
months.sort((a, b) => a > b ? 1 : -1) //从小到大
2. 数组的ES5方法
- Array.isArray()
- 用来判断一个对象是不是数组 ```javascript let obj1 = [] console.log(Array.isArray(obj1)) // true
let obj2 = new Date() console.log(Array.isArray(obj2)) // false
- **indexOf()**
- 用来查找指定元素的位置
- 找不到返回-1
```javascript
let arr = [1, 2, 3, 1]
let index1 = arr.indexOf(1)
console.log(index1) // 0
let index2 = arr.lastIndexOf(1)
console.log(index2) // 3
let index3 = arr.indexOf(4)
console.log(index3) // -1
- forEach()
- 遍历数组,参数为回调函数
- 回调函数里的参数为
- 遍历到的对应元素
- 元素序号
- 数组本身 ```javascript let arr1 = [3, 4, 6] arr1.forEach(val => { console.log(val) // 依次输出数组元素 })
let arr2 = [6, 2, 0] arr2.forEach((val, index, arr) => { arr[index] = val * 2 }) console.log(arr2) // [12, 4, 0]
- **every()**
- 所有回调函数都返回true的时候结果才会返回true,否则返回false
```javascript
let arr = [1, 3, 5, -1]
// 判断arr1数组中的所有元素都是大于0的吗?
let result = arr.every(val => val > 0)
console.log(result) // false
- some()
- 只要有一个回调函数都返回true的时候结果就返回true ```javascript let arr = [1, 3, 5, -1]
// 判断arr1数组中的所有元素有大于0的吗? let result = arr.some(val => val > 0) console.log(result) // true
- **filter()**
- 过滤出满足条件的元素,构成新数组
```javascript
let arr1 = [1, -2, 4, -9, 0]
// 过滤出arr1中所有大于0的元素,组成新数组,原数组不变
let newArr1 = arr1.filter(val => val > 0)
console.log(newArr1) // [1, 4]
console.log(arr1) // [1, -2, 4, -9, 0]
// 过滤出arr2中年龄大于50的对象
let arr2 = [{name: '刘德华', age: 60}, {name: '黎明', age: 50}]
let newArr2 = arr2.filter(val => val.age > 50)
console.log(newArr2)
- map()
- 遍历数组,回调函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组不变 ```javascript let arr = [1, 2, 3] let newArr = arr.map(val => val * 2) console.log(newArr) // [2, 4, 6] console.log(arr) // [1, 2, 3]
// 复制一个数组 let copyArr = arr.map(v => v) console.log(copyArr)
- **reduce()**
- reduce(function(v1, v2), initValue)
- 遍历数组,调用回调函数,将数组元素组合成一个值
- 初始值可选
- 当出现参数是个数组,最终得到一个值这种场景,考虑使用reduce来简化代码
```javascript
let arr = [0, 1, 2, 3]
// 求数组元素之和
let result1 = arr.reduce((val1, val2) => val1 + val2)
console.log(result1) // 6
// 求数组元素的平方和
let result2 = arr.reduce((init, val) => init + val ** 2, 0)
console.log(result2) // 14
// 计算数组中大于0的元素的平方和
let arr = [-1, 1, 3, 0]
let result = arr.filter(val => val > 0).reduce((init, val) => init + val ** 2, 0)
console.log(result) // 10
// 计算返回参数的和
// ...args:剩余参数,作用和一般函数中的arguments类似(箭头函数中不能使用arguments)
let sum = (...args) => args.reduce((res, v) => res + v, 0)
console.log(sum(3, 4)) // 7
console.log(sum(3, 4, 9)) // 16
3. 内部实现
- 实现一个filter函数 ```javascript
function filter(arr, fn) { let newArr = [] for(let v of arr) { if(fn(v)) { newArr.push(v) } } return newArr }
let arr = filter([1, 2, 0], v => v > 1) console.log(arr) // [2]
- **实现一个map函数**
```javascript
function map(arr, fn) {
let newArr = []
for(let v of arr) {
newArr.push(fn(v))
}
return newArr
}
let arr = map([1, 2, 0], v => ++v)
console.log(arr) // [2, 3, 1]
- 实现一个reduce函数 ```javascript let res = reduce([3, -1, 4, 0], (res, v) => res + v ** 2, 0) console.log(res)
/ res v => res+v**2 [0, 3, -1, 4, 0] 0 3 => 9 [ 9, -1, 4, 0] 9 -1 => 10 [ 10, 4, 0] 10 4 => 26 [ 26, 0] 26 0 => 26 [ 26] /
function reduce(arr, fn, initValue){ // 判断是否传进了第三个参数,拼接成临时数组,准备计算 let tmpArr = (initValue === undefined ? [] : [initValue]).concat(arr) while(tmpArr.length > 1){ tmpArr.splice(0, 2, fn(tmpArr[0], tmpArr[1])) } return tmpArr[0] }
<a name="XxCKk"></a>
# 4. 类数组对象
- **长的像数组,但不是数组的对象**
- 属性是数字,带length属性
```javascript
function sum() {
console.log(arguments.length)
console.log(arguments[0])
return arguments.reduce((v1, v2) => v1 + v2) //报错, arguments没有reduce方法,因为它不是数组
}
- 类数组对象转换成数组
- Array.from(arrayLike)
- […arrayLike]
function sum() { //[...arguments].reduce return Array.from(arguments).reduce((v1, v2) => v1 + v2) }