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) 
      }