# 数组

# 什么是数组

数组是一个有序的变量集合。

数组中的每个变量被称之为元素。数组对元素类型没有要求,你可以随意增加任何类型的数据。

// 创建数组的两种方式
// 第一种
let logList = ['abc', 123, false, true, undefined, null];           // 方括号
// 第二种
let userList = new Array('abc', 123, false, true, null, undefined)  // new 关键字

行业中比较推荐第一种,这样写代码可读性强。(我们写出来的代码要优美)

刚刚我们创建的数组长度是 6,我们现在来访问其中的某个元素。请注意,索引的起始值为 0

logList[0]; // abc
logList[1]; // 123
logList[3]; // true
logList[10]; //索引越界了,所以返回 undefined,但不会报错

数组的长度,用 length 表示数组中有多少个元素

logList.length; // 6

TIP

数组的长度是从1开始计算的,但是下标是从0开始的,所以获取数组中的第一个元素的方法是 logList[0],获取数组中最后一个元素的方法是 logList[logList.length - 1]

一次性取出数组中的所有元素

for (let val of logList){
  console.log(val); // 依次输出所有元素
}

我们还可以判断某些变量是不是数组

let fn = (param1, param2, param3) => {
  console.log(Array.isArray(param1))
  console.log(Array.isArray(param2))
  console.log(Array.isArray(param3))
}
// 传入的第三个参数是数组
fn(1, false, [1, 2, 3]);
// false
// false
// true

# 遍历器 Iterator

遍历器(Iterator)是一种接口约定,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

  • 对象内部创建一个指针,默认指向集合中第一个位置
  • 提供 next 方法,可以移动指针指向下一个元素
  • 不断的调用 next 方法,等到结合末尾时 next 函数需要返回 done: true

任意数据类型只要实现了以上的约定,就可以被 for (.. of) 循环处理所有的元素。

我们来体验一下

let Obj = function(arr) {
    this.arr = arr;
    this.index = 0;
    this.next = null;
}
// Symbol 为 ES6 新特性
Obj.prototype[Symbol.iterator] = function() {
    let iterator = { next: next };
    let current = this;
    function next () {
        let val = current.arr[current.index++]
        if (val) {
            return { done: false, value: val };
        } else {
            return { done: true }
        }
    }
    return iterator;
}

let it = new Obj(
  { 0: 1, 1: 2, 2: 3 }
)

for (let v of it) {
    console.log(v); // 依次输出1、2、3
}

目前支持 for (.. of) 循环的数据类型有:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象
  • 只有对象没有默认部署Symbol.iterator属性

# 数组修改

push()unshift() 为数组增加元素

let l = [1, 2, 3];
l.push('b');    // push 向数组的末尾增加 b
// [1, 2, 3, 'b']

l.unshift('a')  // unshift 向数组的开头增加 a
// ['a', 1, 2, 3, 'b']

shift(), pop() 删除数组中的元素

let l = [1, 2, 3];
l.pop();    // pop 删除数组最后一个元素
// [1, 2]

l.shift()  // shift 删除数组中第一个元素
// [1]

splice() 数组的万能方法!从某个位置开始,删除多少,添加任意个元素。返回删除的元素

let a = [1,2,3,4,5]
// 替换掉 2, 3
a.splice(
  1, // 从第 1 位开始
  2, // 删掉 2 个元素
  'a', 'b' // 把这两个元素,从第二位下标处塞进去
);
// [1, "a", "b", 4, 5]

concat() 拼接两个数组,返回一个新的数组

let a = [1,2,3,4,5]
let b = ['a', 'b', 'c']
let c = b.concat(a);
console.log(c); // ['a', 'b', 'c', 1, 2, 3, 4, 5]

join() 根据提供的参数,把数组中的所有元素拼接成字符串

var a = [
  new Date().getFullYear(),
  new Date().getMonth() + 1,
]
console.log(a.join('-')); // '2020-7'

reverse() 反转数组的元素顺序。

let a = [1,2,3,4,5]
console.log(a.reverse()); //  [5, 4, 3, 2, 1]

# 数组遍历

map() 通过指定函数处理数组的每个元素,并返回处理后的数组。

let a = [1,2,3,4,5]
let b = a.map(item => {
  return item + '-' + item
})
console.log(b); // ["1-1", "2-2", "3-3", "4-4", "5-5"]

sort() 数组排序

let a = [1,4,3,5,2]
a.sort();  // 默认排序 正序
a.sort((n1, n2) => n1 - n2); // 正序 [1, 2, 3, 4, 5]
a.sort((n1, n2) => n2 - n1); // 倒叙 [5, 4, 3, 2, 1]

reduce() 将数组元素计算为一个值(从左到右)。

let a = [1,4,3,5,2];
let b = a.reduce((res, item) => {
  return res += item;
}, 0)
console.log(b); // 15

# 数组查询

indexOf(),lastIndexOf() 查找元素在数组中的下标,找不到返回 -1

let a = [1,2,3,5,2];
// 从第 开头 位查找
a.indexOf(2);     // 1
// 从第 末尾 位查找
a.lastIndexOf(2); // 4
// 查询一个数组中没有的元素,返回 -1
a.indexOf(100); // -1
a.lastIndexOf(100); // -1

includes() 判断数组中是否包含某个元素。

let a = [1,2,3,5,2];
a.includes(2);  // true
a.includes(5);  // true
a.includes(100);// false

filter() 过滤数组中的元素,你需要提供过滤函数。

let a = [1,2,3,5,2];
// 找到数组中,大于 2 的元素。
a.filter(n => n > 2); // [3, 5]

slice() 选择数组中的某一段,你需要提供开始截止的下标。

let a = [1,2,3,5,2];
a.slice(2, 4); // [3, 5]
上次更新: 7/6/2020, 11:31:52 PM