一直以来都想好好的理一理 Array 相关的 API 方法,因为关于它的知识点太多了,而且在平时的开发过程中也用得非常频繁,于是打算连载几篇博客将 Array 相关的知识都梳理一遍,一方面是巩固基础,另一方面补充自己知识的空缺。

基础概念

在 JavaScript 中,Array 作为一个全局对象的形式存在着,主要用于构建数组。数组是用于存放一系列元素的集合,其在内存中的存储形式为一段连续的内存地址,而数组的名称其实就是这段连续内存地址的首地址了。

JavaScript 中的数组在定义的时候无需指定元素的类型,也可以不指定数组的长度,甚至可以包含任意数据类型的元素,也就是说 JavaScript 中的各数据类型的数据都可以混合存在于一个数组里面。这些特点和其他一些语言还是存在很大的区别的,比如 Java 里面数组定义的时候必须指定数组中每个元素的类型,而且数组中的每个元素必须保证相同的数据类型,也就是说定义的时候指定的是 int 类型,那么数组里面的每个元素都必须是 int 类型的数据。还有 Java 在定义数组时必须要指定其长度。这样对比下来,可见 JavaScript 中的数组是非常灵活的了。

定义数组

上面说了很多概念性的东西,我都写累了,更不用说大家看了。下面我们就来说说数组创建的几种方式吧!

Let’s show code!

直接量创建

  1. // 创建一个空数组
  2. var empty = []
  3. // 创建一个包含多种数据类型值的数组
  4. var array = ['JavaScript', { book: 'Vue.js' }, () => 'React.js', true, ['CSS']]

这种定义数组的方式,我个人用得比较做,因为它很直接,也很简单、方便、快速。一上来就可以声明一个变量,变量的值就是用 [] 符号包裹的以逗号隔开的可包含多种数据类型值的序列集合,形如上面的示例代码。

构造函数创建

还记得我们上面说到的概念吗:Array 是一个专门用于创建数组的全局对象,下面我们就好好的利用这个全局对象为我们做点事情。

  1. // 创建一个空数组
  2. var empty = new Array()
  3. // 创建一个指定长度的数组
  4. var array1 = new Array(2)
  5. // 创建一个包含多种数据类型值的数组
  6. var array2 = new Array('JavaScript', 1, { book: 'Vue.js' }, true, ['css'])
  7. // 先创建一个空数组,然后给数组元素赋值
  8. var array3 = new Array()
  9. array3[0] = 'JavaScript'
  10. array3[1] = 1
  11. array3[2] = { book: 'Vue.js' }

new 操作符的作用大家想必都知道(如果你还不知道 new 操作符的作用,你可以点击这里查看),它会将函数通过构造函数的形式进行调用并进行实例化。这里我们会通过 new 操作符以构造函数的形式调用 Array 创建数组。第一行代码我们在调用 Array() 时没有传入任何参数,这时会创建一个空数组;第二行代码传递了 Number 类型的数字 2,这时会创建一个长度为 2 的数组,数组里面的元素都是 undefined;第三行代码创建数组时传递了多个元素,最终创建的数组就是这些元素最终组成的数组了;最后一种方式会先创建一个空数组,然后利用下标初始化对应下标的值,创建了 [‘JavaScript’, 1, { book: ‘Vue.js’ }] 的形式的数组。

多维数组

上面介绍了通过多种方式创建一维数组,但是对于数组的存在形式还有多维数组,多维数组中我们接触比较多的就是二维数组了,这里我们就只说说关于二维数组。

为了更好的明白二维数组的存储形式,我们现在看看一维数组的图示吧

WX20190506-231329@2x.png

数组的存储形式以一段连续的内存,所以一维数组的存储形式可以表示为以上图例,其中标注的 array 表示数组的名称,0、1、2 表示数组中各元素的下标。

WX20190506-231054@2x.png

如果上面一维数组图例可以看成是一维坐标系的话,那二维数组就很自然的可以类比为二维坐标系了。在图示中,我们展示了一个名为 days 的二维数组。数组以先横排后竖排的形式进行展示,相当于二维坐标系中的 X 轴和 Y 轴。

二维数组的形式大家都清楚了,那我们就来动手创建一个二维数组吧。

  1. // 直接量形式
  2. var arrays = [[1, 'a'], [2, 'b'], [3, 'c']]
  3. //必须逐层进行赋值
  4. var arrays = new Array()
  5. arrays[0] = new Array()
  6. arrays[0][0] = 1
  7. arrays[0][1] = 'a'
  8. arrays[1] = new Array()
  9. arrays[1][0] = 2
  10. arrays[1][1] = 'b'

上面展示了两种创建二维数组的方式,明显可以看出直接量的形式简单许多,而下面逐层赋值的方式略显复杂。当然在日常的开发中,我们一般会使用多重循环的方式进行多维数组的创建,例如:

  1. var arrays = new Array(3)
  2. for(let i = 0; i < 3; i++) {
  3. var childArr = new Array(2)
  4. for(let j = 0; j < 2; j++) {
  5. childArr[j] = i + j
  6. }
  7. arrays[i] = childArr
  8. }

数组长度 length

length 是 Array 的实例属性。可以通过获取这个属性值得到数组中的元素个数或者通过设置该属性值设置数组中元素的个数。该值是一个无符号 32-bit 的整数,并且总是大于数组最高项的下标。由于 length 值为无符号 32-bit 整数,所以其可表示的范围为 0 到 2^32-1,所以数组的最大长度为 2^32-1,即 4,294,967,295。

  1. // 创建一个数组
  2. var array = new Array('JavaScript', 1, { book: 'Vue.js' }, true, ['css'])
  3. // 获取数组的长度
  4. var arrLen = array.length // 5
  5. // 设置数组的 length 属性值
  6. array.length = 3
  7. // 再次获取数组的长度
  8. var newArrLen = array.length // 3
  9. // 打印下标为 3、4 的元素
  10. array[3] // undefined
  11. array[4] // undefined

数组的 length 属性还有一个非常重要的作用是在利用 for 表达式遍历数组时设置循环的终止条件

  1. // 创建一个数组
  2. var array = new Array('JavaScript', 1, { book: 'Vue.js' }, true, ['css'])
  3. // 遍历打印数组的每个元素
  4. for(let i = 0, len = array.length; i < len; i++) {
  5. console.log(array[i])
  6. }

数组的 length 属性还有一个显著的特点,就是我们通过整数下标为数组设值时,该属性的值会自动变化

  1. // 创建一个空数组
  2. var array = []
  3. // 获取数组 length
  4. array.length // 0
  5. // 通过整数下标为数组设值
  6. array[0] = 0
  7. array.length // 1
  8. array[1] = 1
  9. array.length // 2
  10. // 有点酷耶!

数组下标

数组基本上可以支持所有数据类型的下标

  1. // 创建一个空数组
  2. var array = []
  3. // 整数 毋庸置疑!
  4. array[0] = 0
  5. array[0] // 0
  6. array.length // 1
  7. // 字符串 试试
  8. array['hello'] = 'hello'
  9. array['hello'] // hello
  10. array.length // 1
  11. // 对象 unbelievable
  12. array[{a: 1}] = {a: 1}
  13. array[{a: 1}] // {a: 1}
  14. array.length // 1
  15. // 函数 unbelievable
  16. array[() => {}] = 'unbelievable'
  17. array[() => {}] // unbelievable
  18. array.length // 1

我的尝试到此为止,大家可以继续试验,如果发现有不支持的可以在下面评论艾特我。

虽然数组下标支持很多,但是个人推荐只使用整数形式,原因有以下几点:

  • 仔细观察上面试验代码片段,你是不是已经发现了只有根据整数形式的下边进行赋值时,数组的 length 属性才会自动变化

  • 如果你想通过除整数形式以外的下标进行赋值,JavaScript 为你提供了另外一种专门处理这中类型的数据类型 —— Object

  • 如果你通过函数、对象等复杂类型下标进行赋值,你要清楚语言内部的处理原理 —— 会将复杂类型转为基础类型,然后进行对应的赋值、查找操作,不然你会觉得上面示例代码中的最后两个例子片段会特别诡异

上面有提到,针对全是整数类型的下标数组的遍历,我们可以使用 for 表达式进行,而如果数组使用了除整数以外的数据类型下标,可以使用 for in 进行数组遍历

  1. // 针对上面示例代码所得数组遍历
  2. for(let index in array) {
  3. console.log(index, array[index])
  4. }
  5. // 0 0
  6. // hello hello
  7. // [object Object] {a: 1}
  8. // () => {} unbelievable

总结

说到这里,关于数组的基础知识就说完了,主要说了数组的概念,数组的两种定义方式,并由此引申出了多维数组,然后说了数组的 length 属性和数组的下标,算是对数组有了一个基本的认识。关于下一篇,我们将会讲解数组相关的方法,敬请期待!