本文共 7134 字,大约阅读时间需要 23 分钟。
如需转载, 请咨询作者, 并且注明出处.
有任何问题, 可以关注我的微博: , 或者添加我的微信: 372623326
几乎所有的编程语言都原生支持数组类型,因为数组是最简单的内存数据结构。
数组通常情况下用于存储一系列同一种数据类型的值。
但在JavaScript里,也可以在数组中保存不同类型的值。但我们还是要遵守最佳实践,别这么做(大多数语言都没这个能力)。
事实上, 如果你之前已经学习了JavaScript的基础知识, 那么数组这部分可以直接跳过.
因为在基础知识中, 是要求我们灵活使用数组的, 所以大部分人应该对这部分没有问题, 但是这里我还是花费一些篇章来带着大家一起学习一下数组.
因为数据结构中数组是其中很重要的一环, 直接跳过总觉得少点什么.
为什么使用数组?
假如有这样一个需求:保存自己多个朋友的名字。可以这么做:
// 保存班级中所有学生的名字var name1 = "Tom"var name2 = "Lily"var name3 = "Lucy"var name4 = "Lilei"var name5 = "Coderwhy"
这不是一个好的解决方案
很明显, 这种情况下, 我们通常会使用数组来解决:
// 使用数组来保存学生名字var names = ["Tom", "Lily", "Lucy", "Lilei", "Coderwhy"]
创建和初始化数组
用JavaScript声明、创建和初始化数组很简单,就像下面这样:
// 创建和初始化数组var daysOfWeek = new Array()var daysOfWeek = new Array(7)var daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')
代码解析:
new
关键字,就能简单地声明并初始化一个数组new
创建数组并不是最好的方式。如果你想在JavaScript中创建一个数组,只用中括号([]
)的形式就行了使用中括号([]
)创建数组
var daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
数组长度和遍历数组
如果我们希望获取数组的长度, 有一个length属性
// 获取数组的长度alert(daysOfWeek.length)
也可以通过下标值来遍历数组:
// 普通for方式遍历数组for (var i = 0; i < daysOfWeek.length; i++) { alert(daysOfWeek[i])}// 通过foreach遍历数组daysOfWeek.forEach(function (value) { alert(value)})
我们来做一个练习:
// 求菲波那切数列的前20个数字var fibonacci = []fibonacci[0] = 1fibonacci[1] = 1for (var i = 2; i < 20; i++) { fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]}alert(fibonacci)
数组中常见的操作有: 添加元素、删除元素、修改元素、获取元素.
添加元素
JavaScript中, 进行我们上述的操作都比较简单: 因为语言本身都已经封装好了这些特定.
假如我们有一个数组: numbers, 初始化0~9
// 初始化一个数组var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
添加一个元素到数组的最后位置:
// 添加一个元素到数组的最后位置// 方式一:numbers[numbers.length] = 10// 方式二:numbers.push(11)numbers.push(12, 13)alert(numbers)
在数组首位插入一个元素:
// 在数组首位插入一个元素for (var i = numbers.length; i > 0; i--) { numbers[i] = numbers[i-1]}numbers[0] = -1alert(numbers) // -1,0,1,2,3,4,5,6,7,8,9,10,11,12,13
上面代码实现的原理是怎样的呢?
img
考虑上面代码实现的性能怎么呢?
当然, 我们在数组首位插入数据可以直接使用unshift方法
// 通过unshift在首位插入数据numbers.unshift(-2)numbers.unshift(-4, -3)alert(numbers) // -4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13
删除元素
如果希望删除数组最后的元素, 可以使用pop()方法
// 删除最后的元素numbers.pop()alert(numbers) // -4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12
如果我们希望移除的首位元素, 自己实现代码:
// 删除首位的元素for (var i = 0; i < numbers.length; i++) { numbers[i] = numbers[i+1]}numbers.pop()alert(numbers)
当然, 我们可以直接使用shift方法来实现:
numbers.shift()alert(numbers)
任意位置
任意位置?
一方面, 我们可以自己封装这样的函数, 但JS已经给我们提供了一个splice方法
通过splice删除数据
// 删除指定位置的几个元素numbers.splice(5, 3)alert(numbers) // -4,-3,-2,-1,0,4,5,6,7,8,9,10,11,12,13
代码解析:
如果我们希望使用splice来插入数据呢?
// 插入指定位置元素numbers.splice(5, 0, 3, 2, 1)alert(numbers) // -4,-3,-2,-1,0,3,2,1,4,5,6,7,8,9,10,11,12,13
代码解析:
如果我们希望使用splice来修改数据呢?
// 修改指定位置的元素numbers.splice(5, 3, "a", "b", "c")alert(numbers) // -4,-3,-2,-1,0,a,b,c,4,5,6,7,8,9,10,11,12,13
代码解析:
上面学习的是对数组的一些基本操作.
JavaScript中添加了很多方便操作数据的方法, 我们一些来简单回顾一下.
常见方法
我们先对常见的方法简单来看一下
方法名 | 方法描述 |
---|---|
concat | 连接2个或更多数组,并返回结果 |
every | 对数组中的每一项运行给定函数,如果该函数对每一项都返回 true ,则返回true , 否则返回false |
filter | 对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组 |
forEach | 对数组中的每一项运行给定函数。这个方法没有返回值 |
join | 将所有的数组元素连接成一个字符串 |
indexOf | 返回第一个与给定参数相等的数组元素的索引,没有找到则返回-1 |
lastIndexOf | 返回在数组中搜索到的与给定参数相等的元素的索引里最大的值 |
map | 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组 |
reverse | 颠倒数组中元素的顺序,原先第一个元素现在变成最后一个,同样原先的最后一个元素变成了现在的第一个 |
slice | 传入索引值,将数组里对应索引范围内的元素作为新数组返回 |
some | 对数组中的每一项运行给定函数,如果任一项返回 true ,则结果为true , 并且迭代结束 |
sort | 按照字母顺序对数组排序,支持传入指定排序方法的函数作为参数 |
toString | 将数组作为字符串返回 |
valueOf | 和 toString 类似,将数组作为字符串返回 |
数组合并
数组的合并非常简单, 使用concat即可(也可以直接+进行合并)
// 数组的合并var nums1 = [1, 2, 3]var nums2 = [100, 200, 300]var newNums = nums1.concat(nums2)alert(newNums) // 1,2,3,100,200,300newNums = nums1 + nums2alert(newNums) // 1,2,3,100,200,300
迭代方法
为了方便操作数组, JS提供了很多迭代器方法, 我们来回顾一下
every()方法
every()练习:
// 定义数组var names = ["abc", "cb", "mba", "dna"]// 判断数组的元素是否都包含a字符var flag = names.every(function (t) { return t.indexOf('a') != -1})alert(flag)
some()方法
some()练习
// 定义数组var names = ["abc", "cb", "mba", "dna"]// 判断数组中是否包含有a字符的字符var flag = names.some(function (t) { alert(t) return t.indexOf("a") != -1})alert(flag)
forEach()方法
forEach的使用
// 定义数组var names = ["abc", "cb", "mba", "dna"]// forEach的使用names.forEach(function (t) { alert(t)})
filter()方法
filter()的练习:
// 定义数组var names = ["abc", "cb", "mba", "dna"]// 获取names中所有包含'a'字符的元素var newNames = names.filter(function (t) { return t.indexOf("a") != -1})alert(newNames)
map()方法
map()练习:
// 定义数组var names = ["abc", "cb", "mba", "dna"]// 在names中所有的元素后面拼接-abcvar newNames = names.map(function (t) { return t + "-abc"})alert(newNames)
reduce方法
我们单独拿出reduce方法, 因为这个方法相对来说难理解一点
首先, 我们来看这个方法需要的参数:
arr.reduce(callback[, initialValue])
参数
有些晦涩难懂, 我们直接看例子
使用for实现:
// 1.定义数组var numbers = [1, 2, 3, 4]// 2.for实现累加var total = 0for (var i = 0; i < numbers.length; i++) { total += numbers[i]}alert(total) // 10
使用forEach简化for循环
// 3.使用forEachvar total = 0numbers.forEach(function (t) { total += t})alert(total)
使用reduce方法实现
// 4.使用reduce方法var total = numbers.reduce(function (pre, cur) { return pre + cur})alert(total)
代码解析:
似乎和forEach比较没有太大的优势呢?
initialValue还需要讲吗?