# 数组

# 创建数组

数组的每一项可以用来保存任何类型的数据,数组的大小可以动态改变。本质上是对象

var colors = new Array(); // 创建一个空数组,括号里可以填数组长度
var colors = []; // 创建一个空数组
var colors = ["red", "blue", "green"]; // 创建一个 3 项的数组

console.log(colors.toString());
console.log(colors.valueOf());
console.log(colors); // 都返回的是以逗号分割的字符串的形式返回数组项

注意

如果数组中的某一项值是 null 或 undefined,那么该值在 toString()valueOf()toLocalString()join() 方法中返回的是空字符串

如果给 length 赋值可能会导致数组截断,实际开发中不要给 length 赋值,数组可以添加属性,但是并不添加到数组长度内

&

下标不连续的叫做稀松数组

检测是否为数组:Array.isArray(colors),返回 Boolean 类型,具体实现:

var isArray = Function.isArray || function (o) {
  return typeof o === 'object' && Object.prototype.toString.call(o) === '[Object Array]'
}

# 数组元素的读写

数组通过 [] 操作符即可访问和写入一个元素,数组也是对象,使用 [] 访问时就像用 [] 访问对象的属性一样

区分数组的索引和对象的属性名:所有的索引都是属性名,但只有 0 ~ 2^32^ - 2 之间的整数属性名才是索引

var arr = [1, 3, 5]
arr[-1.23] = true // 给数组添加一个属性名为 -1.23 的元素
console.log(arr) // [1, 3, 5, -1.23: true]

数组的索引是对象的属性名的一种特殊形式,这意味着 JavaScript 中没有数组“越界”错误的概念,当访问了不存在的属性时只会得到 undefined

# 数组的遍历

遍历数组有以下方法:

  1. for 循环
  2. for/in 循环

for/in 循环:循环每次将一个可枚举的属性名(包括数组索引)赋值给循环变量,不存在的索引将不会遍历到:

for (var index in array) {
  // for/in 循环会枚举继承的属性名
  // 每一轮循环需要判断是否是继承的属性
  if (!array.hasOwnProperty(index)) {
    continue
  }
  var value = array[index]
}

&

for/in 循环可以以不同的顺序遍历对象的属性,如果程序依赖于遍历的顺序就需要用普通的 for 循环

数组的长度应该是在遍历之前就应该查询出来,而不是每一次循环都要查询

# 数组的方法

# 栈方法

  • push():可以接收任意数量的参数,并把它们逐一添加到数组末尾,并返回修改后数组的长度。
  • pop():删除数组最后一项,将数组的长度减 1,然后返回被删除的项。

# 队列方法

  • shift():删除数组中的第一项并返回该项,同时将数组的长度减 1
  • unshift():可以在数组前端添加任意个项并返回数组的长度
  1. pushpop 可以用来模拟栈结构
  2. pushshift 用来模拟队列结构

# 重排序方法

  • reverse():对数组进行反转
  • sort():默认升序,调用每一项的 toString() 方法,然后比较得到的字符串。可以接收一个比较函数作为参数
colors.sort(function () {
  // 如果第一个参数小,返回一个负数
  // 如果第一个参数大,返回一个整数
  // 两者相等则返回 0
  return a - b
});

# 数组的操作方法

  • splice() 删除(增加)指定位置和数量的元素
    • 删除:arr.splice(3, 3) 从数组索引3开始删除3个元素,如果省略第二个参数则一直删除到数组结尾
    • 增加:a.rrsplice(3, 0, 1, 2, 3) 第三个参数以及后面的就是要添加到数组里面的值,如果索引越界,按照边界值处理
  • concat():不影响原数组
    • 复制当前数组并返回副本,如果参数是一个或多个数组,则把它的每一项都添加到结果数组中,如果参数不是数组,就直接添加到数组末尾
    • 如果参数是数组中嵌套了数组,则会把嵌套的数据原封不动的当作一个元素添加进去
  • slice():不会影响原数组
    • arr.slice(起始位置下标, 结束位置下标):返回包含起始位置但不包含结束位置的项得到一个新数组,如果只有一个参数,则返回从指定位置到数组末尾的所有项
    • arr.slice(-3, -1):如果是负数,则从末尾计算。表示从倒数第三个到倒数第一个但不包括倒数第一个。
    • 如果不写结束下标就直接取到末尾
    • 如果不传任何参数,默认将数组中的元素放到一个新的数组中原样返回
  • fill()
    • arr.fill(数据):将数据的所有项,填充为指定的数据
    • arr.fill(数据, 开始下标):将数组从开始下标到数组末尾填充为指定数据
    • arr.fill(数据,开始下标, 结束下标):将数组从开始下标到结束下标(取不到)填充为指定数据
  • indexOf(数据):从数组的开头开始查找传进去的数据,返回的是查找的项在数组中第一次出现的位置,必须是严格相等的,如果没有找到则返回 -1
  • lastIndexOf(数据):从数组的末尾开始查找,返回的也是第一次找到该数据的位置

find() 和 fliter() 的区别:

  • find:返回通过测试的(函数内判断)数组的第一个元素,返回的是单个值
  • fliter:创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素

# 数组的本质

  1. 数组的本质是对象(引用类型),在数组中存放的是地址
  2. 复制一个数组(新创建了一个对象)
var arr2 = arr1.slice();
//这个arr2就是一个新的对象
  1. 可以利用数组实现斐波那契数列
var a = [];
a[0] = 1;
a[1] = 1;
for (let i = 2; i < 10; i++) {
  a[i] = a[i - 1] + a[i - 2];
}

for (let i = 0; i < 10; i++) {
  console.log(a[i]);
}

# 真数组与伪数组转换

真数组转成伪数组

// 把对象转成了伪数组
let arr = [1, 3, 5, 7, 9]
let obj = {}
;[].push.apply(obj, arr)

所做的操作如下:

  1. 通过[].push找到数组中的push方法
  2. 调用apply()方法使 this 指向 obj
  3. 将实参 arr 中的数据取出依次调用push方法加入到 obj 中

伪数组转成真数组

let obj = {
  0: 'hhh',
  1: 'eee',
  length: 2
}
let arr = []
;[].push.apply(arr, obj) // 该方法在 IE8 及以下不支持
let arr2 = [].slice.call(obj) // 实际开发中使用这个方法

# 数组去重

  • 利用 Set 数据结构
  • Array.from方法
;[...new Set([1, 3, 4, 4, 4, 5, 5])]

Array.from(new Set([1, 3, 4, 4, 4, 5, 5]))

# 多维数组

数组是一个对象,里面可以存储任何类型的值,用数组嵌套数组可以实现多维数组

var a = [];
a[0] = ['a', 'b', 'c'];
a[1] = ['d', 'e', 'f'];
a[2] = ['g', 'h', 'i'];
// 输出数组
for (let i = 0; i < a.length; i++) {
  for (let j = 0; j < a[i].length; j++) {
    console.log(a[i][j]);
  }
}

# 数组方法参考

方法名 描述
concat 连接 2 个或更多数组,并返回结果
every 对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true
filter 对数组中的每一项运行给定函数,返回给定函数会返回 true 的项组成的数组
forEach 对数组中的每一项运行给定函数,没有返回值(参数:数组元素,[索引,数组])
join 将所有的数组元素连接成一个字符串
indexOf 返回第一个与给定参数相等的数组元素的索引,没有找到则返回-1
lastIndexOf 返回指定参数在调用该方法的字符串中最后出现的位置,没有则返回-1
map 对数组中的每一项运行给定函数,返回一个数组,这个数组是由每次函数执行之后的结果组成
reverse 反转元素顺序
slice 传入索引值,返回一个指定索引范围内的新数组,如果不传默认将原数组组成新数组返回
some 对数组中的每一项运行给定函数,如果任一项返回true,则返回true
sort 按照字母顺序对数组排序,可以传递参数指定排序方法
toString 将数组作为字符串返回
valueOf 将数组作为字符串返回
更新: 3/28/2020, 9:40:55 AM