数组

@Array
思维导图

概述 Introduction

定义 Defined

实例属性 Instance properties

  1. length - 数组长度;可以任意赋值:少于实际个数,数据会丢失,但是数据仍然在内存中;多于实际个数,值为undefined
  2. index - 数组元素的位置,从0开始

Usage

访问 Access

赋值 Assignment

解构赋值 Destructuring

扩展运算符 spread operator

如何清空数组?
[] 直接赋值和解构赋值对数据的影响
1. 基本数据类型
let a0 = [1, 2, 3]
// 直接赋值;会彼此影响
let a1 = a0
a0.push(4)
// 解构赋值:相当于重新赋值;不会彼此影响
let a2 = [...a0]
a2.push(5)
console.log(a0, a1, a2);
2. 引用数据类型
let obj0 = [{ id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' }]
console.log(obj0);
let obj1 = obj0
obj0.push({ id: 4, name: '赵六' })
let obj2 = [...obj0]
obj0.push({ id: 5, name: '老郭' })
obj2.push({ id: 5, name: '孙七' })
console.log(obj0, obj1, obj2);
      

静态方法 Static methods

from()

isArray()

实例方法 Instance methods

一般方法 Normal

一般方法 Normal
item desc
push() 添加元素到数组末尾
unshift() 添加元素到头部
pop() 移除数组末尾元素并返回
shift() 移除数组头部元素并返回
concat() 数组连接;返回一个新数组;不会修改原数组;不会去重
join() 数组元素按照指定的分隔符连接为字符串
slice(start,end)
Returns a copy of a section of an array.
取子串 - 选取串中位置|索引从 start 到 end 的部分;不包括 end
返回:一个新的数组/字符串
原数组:不变
start不指定,从0开始;end 不指定,截取到末尾
目标位置为负数时,反向截取;最后一位是-1;倒数第二位是-2,依次类推;可以用于获取后缀名;
splice(start,count[,el...])
Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
从原来数组中截取|删除指定长度的字符串
返回:删除的数据项
原数组:被修改
在删除的基础上,还可以插入新的元素el;如果 count 为0,则不删除
要清楚每个函数有无返回?如果有的话,返回值是什么?原数组有没有破坏?
[] 示例
let arr0 = [1, 2, 3];
let arr1 = [3, 4, 5];
console.log(arr0.concat(arr1));//1, 2, 3, 3, 4, 5
console.log(arr0);//1, 2, 3
console.log(arr0.join('-'));//1-2-3
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let res = arr.slice(2, 4);
console.log(res);//3,4
console.log(arr);//不变
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let res = arr.splice(2, 2);
console.log(res);//[3,4]
console.log(arr);//[1,2,5,6,7,8,9]
arr.splice(2, 1, 8, 8);
console.log(arr);//[1,2,8,8,6,7,8,9];5被删除,插入|增加了2个8
[] 应用 - 洗牌 Shuffle

迭代方法 Iteration

除了使用通用方法 for 外,还可以使用专有方法进行数据迭代
迭代方法 Iteration
item desc
forEach()
返回:没有
对数组中的每一项执行给定函数。本质上与使用 for 循环迭代数组一样
原数组:不会被修改;仅仅使用数据
无法中断
map()
对数组中的每一项执行给定函数,返回每次函数调用的结果组成的数组
适合创建包含的项与另一个数组一一对应的数组 - 映射
返回:新数组
原数组:不会被修改
every()
对数组中的每一项执行给定函数;如果该函数对 每一项 都返回 true,则返回 true
返回:布尔值
原数组:不会被修改
some()
对数组中的每一项执行给定函数;如果该函数 有一项 返回 true,则返回 true
返回类型:布尔值
原数组:不会被修改
filter()
对数组中的每一项执行给定函数,返回执行结果为 true 的项组成的数组 - calls the predicate function one time for each element in the array
返回:符合条件的新数组
原数组:不会被修改
find()
查找满足提供的测试函数的 第一个 数据项
返回:查找到的数据项;若没有则返回 undefined
原数组:不会被修改
如果有,则立即返回;不会再继续测试后面的数据项
findIndex()
返回数组中满足提供的测试函数的 第一个 元素的索引
返回:查找到的数据项的索引;若没有找到对应元素则返回 -1
原数组:不会被修改
如果有,则立即返回;不会再继续测试后面的数据项
querySelectorAll 返回的是一个静态的 NodeList:NodeList 是类数组结构,且具有 forEach 方法
getElementsByTagName 返回的是一个动态的 HTMLCollection:HTMLCollection 也是一个类数组结构,但它没有 forEach 方法
filter 会遍历整个数组并返回所有匹配项;find 和 findIndex 在找到第一个匹配项后就会停止遍历,性能更优
[] 示例
let data = [{ id: 10, name: 'gl' }, { id: 11, name: 'cq' }, { id: 12, name: 'sz' }]
提取特征数据 - 从API请求的数据中获取数据项的 name 展示;也可以在请求时指定需要的数据,具体情况看API的支持
提取1个 - 返回每个数据项的 name 组成的数组;需要使用变量接受新数组
let res = data.map(item => item.name)
提取多个 - 返回每个数据项的 name、desc 组成的数组;需要使用变量接受新数组
let res = data.map(item => ({name: item.name, desc:item.desc}))
修改格式 - 修改每个数据项的 name 为大写;无需使用变量接受
data.map(item => item.name = item.name.toUpperCase())
添加属性 - 为每个数据项增加一个数量,初始化为1;如添加到购物车;无需使用变量接受
data.map(item => item.num = 1)
添加属性 -简单数组生成索引数组;改变了数据结构,需要使用变量接受新数组
let data = ['gl', 'cq', 'sz', 'sh', 'gz']
let res = data.map((item, ind) => ({ id: ind, location: item }))
如果仅仅是修改数据项的属性,无需使用变量接受
[] 创建 DOM
使用 join() 将数组转化为字符串使用
fetch('/utils/data/message.json')
.then(res => res.json())
.then(res => {
  console.log(res);
  let json = res.cont.map(item => `
  • ${item.msg}
  • `).join('') ul.innerHTML = json })
    [] 全选业务
    全选为真,所有待选项都选中
    全选为假,所有待选项都不选中
    如果有一个待选项没有选中,则全选为假 - 每一个待选项都为真,全选才为真
    checkAll = options.every(item => item.check)
    [] 应用:查找数据列表中是否有符合条件的数据项,避免重名
    let arr = [0, 1, 2, 3, 4, 5]
    let flag = arr.some(item => item > 5)
    console.log(flag);  // false      
    let obj = [{ id: 10, name: 'gl' }, { id: 11, name: 'cq' }, { id: 12, name: 'sz' }]
    let flag = obj.some(item => item.name == 'sz')
    console.log(flag); // true     
    [] 模糊查询
    根据名字是否包含指定的关键字过滤结果
    goods.filter(item => item.name.includes(keyword))
    [] 获取偶数
    let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    let res = arr.filter(item => item % 2 === 0)
    [] 删除指定特征如 id 的数据项 - 购物车、歌单
    let data = [{ id: 10, name: 'gl' }, { id: 11, name: 'cq' }, { id: 12, name: 'sz' }]
    let res = data.filter(item => item.id != 11)
    函数封装
    function delItem(dataItem) {
      data = data.filter(item => item.id != dataItem.id)
    }
    [] 根据 id 获取/请求商品
    let obj = [{ id: 10, name: 'gl' }, { id: 11, name: 'cq' }, { id: 12, name: 'sz' }]
    let res = obj.find(item => item.id === 11)
    console.log(res); // { id: 11, name: 'cq' }
    [] 添加到购物车
    根据 id 查找购物车,如果有,则数量 +1;如果没有,则新增一个数量值对,为 1
    const existingItem = cart.find(item => item.id === product.id)
    if (existingItem) {
      existingItem.quantity++
    } else {
      cart.push({ ...product, quantity: 1 })
    }

    归并方法 Subtotal

    归并方法 subtotal
    item desc
    reduce() reduce()方法从数组的第一项开始,逐个遍历到最后
    reduceRight() 从数组的最后一项开始,向前遍历到第一项
    [] 应用- 数组求和
    1. 普通数组
      let sum = arr.reduce((pre, cur, index, array) => {
          return pre + cur;
      })
    2. 对象数组 - 具有数值属性 price 和 quantity
      let sum = goods.reduce((total, item) => {
        return total + item.price + item.quantity;
      }, 0)

    排序方法 Sort

    排序方法 Sort
    item desc
    sort()
    不指定比较函数
    默认根据数据项 UTF-16 编码升序比较 - The default sort order is ascending
    sort(compareFn) 指定比较函数 - 按照参数进行排序
    [] 示例
    1. 简单数组
    const arr = [1,45,6,2,4,5]
    //升序
    arr.sort(); //[1, 2, 4, 45, 5, 6]
    //降序
    arr.sort().reverse(); //[6, 5, 45, 4, 2, 1]
    const arr = ['banana', 'apple', 'cherry'];
    arr.sort(); // ['apple', 'banana', 'cherry']
    arr = [1,45,6,2,4,5]
    //升序
    arr.sort((a, b) => a - b);  //[1, 2, 4, 5, 6, 45]
    //降序
    arr.sort((a, b) => b - a);  //[45, 6, 5, 4, 2, 1]
    2. 对象数组 - 按年纪 age 排序
    //升序
    obj.sort((a, b) => a['age'] - b['age']);
    //降序
    obj.sort((a, b) => b['age'] - a['age']);
    . 封装函数使用 - 根据 key 排序
    const sortUp = (key) => {
      arr.sort((a, b) => {
        return a[key] - b[key]
      })
    }
    const sortDown = (key) => {
      arr.sort((a, b) => {
        return b[key] - a[key]
      })
    }
    为什么连续测试结果相等?
    3. 字符数组排序
    . 如果需要根据字符排序,需要使用比较函数 localeCompare()
    . 按字符升序排序
    obj.sort((a, b) => {
      return a.name.localeCompare(b.name)
    })    
    . 按字符降序排序
    obj.sort((a, b) => {
      return b.name.localeCompare(a.name)
    })    
    [] 应用 - 排序表格