JS没有真正的数组,是用对象模拟

  • 元素的数据类型可以不同
  • 内存不一定连续(随机存储)
  • 数字下标其实是字符串,arr[1]是自动把数字转为字符串
  • 数组可以有任何key, 比如arr[‘xxx’] = ‘aaa’

创建一个数组

新建

  1. let arr = [1, 2, 3]
  2. let arr = new Array(1, 2, 3) // 参数是元素
  3. let arr = new Array(3) // 只给一个参数是length

转化

  1. let arr = '1,2,3,4'.split(',') // 字符串转数组
  2. let arr = "abcdefg".split('')
  3. let arr = Array.from("123abc")

Array.from()会尝试将不是数组的东西转为数组
image.png

伪数组

有数组形式,但没有数组共有属性(pop, push)的数组称为伪数组

  1. let divList = document.querySelectorAll('div') // 伪数组
  2. let divArr = Array.from(divList) // 转为真数组

合并与截取

  1. arr1.concat(arr2) // 合并2个数组
  2. arr1.slice(1) // 从index 1开始截取
  3. arr1.slice(1, 3) // 截取索引1到3
  4. // 注意,JS只提供浅拷贝

删元素

delete

  • length = 最大整数key+1
  • 用delete删除元素,形成empty空位元素不影响length

image.png

有空位元素的数组称为“稀疏数组”,不建议使用

更改length

直接更改length也可以删元素
image.png

推荐的方法

  1. let arr = [1, 2, 3, 4, 5]
  2. arr.pop() // 删除最后一个元素,并返回被删的元素值
  3. arr.shift() // 删除第一个元素,并返回被删的元素值
  4. arr.splice(1, 2) // 从index=1开始删除2个元素, 并返回被删的元素值
  5. arr.splice(1, 2, 'x') // 删除之后,添加元素'x'
  6. arr.splice(1, 2, 'x', 'y') // 删除之后添加元素'x', 'y'

查元素

for循环

  1. let arr = [1, 2, 3, 4]
  2. arr.x = 'xxx'
  3. Object.keys(arr) // ["0", "1", "2", "3", "x"]
  4. // in操作符会列出所有key(数字和非数字)
  5. for (let key in arr) {
  6. console.log(`${key}:${arr[key]}`)
  7. }
  8. // 只遍历数字key
  9. for (let i = 0; i < arr.length; i++ ) {
  10. console.log(`${i}:${arr[i]}`)
  11. }

(${expression})中的引号是反引号 ``

forEach

**forEach()** 方法对数组的每个元素执行一次给定的函数。

  1. let arr = ['a', 'b', 'c'];
  2. arr.forEach(function(element){console.log(element)})
  3. arr.forEach(element => console.log(element));
  4. arr.forEach(function(xxx,yyy){
  5. console.log(`${yyy}:${xxx}`)
  6. })
  7. arr.forEach((xxx,yyy) =>
  8. console.log(`${yyy}:${xxx}`)
  9. )
  10. // 参数依次为:元素,索引,数组本身
  11. arr.forEach(function(element, index, arr){do something})

for 循环与 forEach的区别:

  • for循环可以break和continue,forEach只能对每个元素执行,直到结束
  • for循环是块级作用域,forEach有函数作用域

查看单个属性

arr[key] 用key访问元素

  1. let arr = [1, 2, 3]
  2. arr[4] // 越界返回 undefined

indexOf() 查找某个值的索引

  1. let arr = [1, 2, 3, 4]
  2. arr.indexOf(1)
  3. arr.indexOf('xxx') // -1表示未找到

find(fn) 找出第一个符合条件的元素

  1. let arr = [1, 2, 3, 4, 5]
  2. // 找出第一个大于2的elment值
  3. arr.find(element => element > 2)
  4. // 找出第一个大于2的elment值的索引
  5. arr.findIndex(element => element > 2)
  6. // 和forEach()一样可以传3个参数
  7. arr.find((element, index) => console.log(`${index}:${element}`))

增/改

插入元素

  1. let arr = []
  2. // 在尾部插入
  3. arr.push('a')
  4. arr.push('b','c','d')
  5. // 在头部插入
  6. arr.unshift(100)
  7. // 在中间插入
  8. arr.splice(2, 0 , 'x', 'y')

排列顺序

sort()如果没有指明 compareFunction , 则按每个字符的Unicode位点进行排序

  1. let arr = [1, 100, 0 , -1, 'a', 'z', 6, 'c']
  2. arr.sort()
  3. // [-1, 0, 1, 100, 6, "a", "c", "z"]

sort()指明compareFunction

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。 ```javascript // 如果是比较字符串,必须返回确定的值 let arr = [1, 100, 20, ‘a’, 50, ‘z’, 33, ‘f’] arr.sort(function(a,b){ if (a > b) {return 1} else if (a === b) {return 0} else {return -1} })

// 如果只比较数字,可以只返回a-b let arr = [1,5,7,100,2,3,40] arr.sort((a,b) => a - b) // 升序 arr.sort((a,b) => b - a) // 降序

  1. **`reverse()`** 反转数组
  2. ```javascript
  3. let arr = [1, 100, 0 , -1, 'a', 'z', 6, 'c']
  4. arr.reverse()
  5. // ["c", 6, "z", "a", -1, 0, 100, 1]
  6. /* 反转字符串 */
  7. let str = "aksmew193s"
  8. str = str.split('').reverse().join('') // "s391wemska"

数组变换

image.png
**map()** 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

  1. let arr = [1,2,3,4,5,6]
  2. arr.map(item => item * item)
  3. arr.map(Math.sqrt)

**filter()** 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

  1. let arr = [1,2,3,4,5,6]
  2. arr.filter(item => item%2 === 0 ? true : false)
  3. arr.filter(item => item%2 === 0)

**reduce()** 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

  1. /* 求和 */
  2. let arr = [1, 2, 3, 4, 5, 6]
  3. let sum = 0
  4. for(let i=0; i<arr.length; i++){
  5. sum += arr[i]
  6. }
  7. console.log(sum)
  8. arr.reduce((sum,item)=>sum+item, 0) // 0是累加器sum的初始值
  9. arr.reduce((sum,item)=>sum+item) // 不提供初始值,默认为第一个元素
  10. /* 实现filter()功能 */
  11. let arr = [1, 2, 3, 4, 5]
  12. arr.reduce((result, item)=>{
  13. if(item%2 === 1){
  14. return result
  15. }else{
  16. return result.concat(item)
  17. }
  18. }, [])
  19. arr.reduce((result, item)=> result.concat(item%2 === 1 ? [] : item), [])

习题

1. 把数字变成星期

  1. let arr = [0,1,2,2,3,3,3,4,4,4,4,6]
  2. let arr2 = arr.map((i)=>{
  3. const hash = {0:'周日',1:'周一',2:'周二',3:'周三',4:'周四',5:'周五',6:'周六'}
  4. return hash[i]
  5. })
  6. console.log(arr2) // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']

2. 找出所有>60分的成绩

  1. let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
  2. let scores2 = scores.filter(item => item > 60)
  3. console.log(scores2) // [95,91,82,72,85,67,66, 91]

3. 算出所有奇数之和

  1. let scores = [95,91,59,55,42,82,72,85,67,66,55,91]
  2. let sum = scores.reduce((sum, n)=>{
  3. return n%2 === 1 ? sum+n : sum
  4. },0)
  5. console.log(sum) // 奇数之和:598

4. 面试题

  1. let arr = [
  2. {名称:'动物', id:1, parent: null},
  3. {名称:'狗', id:2, parent: 1},
  4. {名称:'猫', id:3, parent: 1}
  5. ]
  6. // 数组变成对象
  7. arr.reduce((result, item)=>{
  8. if (item.parent === null) {
  9. result.id = item.id
  10. result['名称'] = item['名称']
  11. } else {
  12. delete item.parent
  13. item.children = null
  14. result.children.push(item)
  15. }
  16. return result
  17. }, {id:null, children:[]})
  18. // 得到结果
  19. {
  20. id:1, 名称: '动物', children:[
  21. {id:2,名称:'狗',children:null},
  22. {id:3,名称:'猫',children:null},
  23. ]
  24. }