菜鸟重学 JavaScript 之 数组
我们知道对象很好用,但是对象中的元素是无序的(如果对象中的键是数字的话,会按照数字的顺序,但是其他非数字为键的键值对则会按照添加顺序排序)。在某种情况下这并不能满足我们的需求。数组便能解决这个问题。实际上在 JavaScript 中数组是一种特殊的对象,例如在控制台输入:
let arr = [1, 2, 3] typeof arr //"object" 复制代码
JavaScript 为数组做了大量的封装,提供了很多方法和属性,为了使数组运行得更快,做了很多优化。但是如果我们误用数组,JavaScript 引擎则会认为是普通对象,针对数组的优化将失效。例如此乱杀
let fruits = []; // 创建一个数组 fruits[99999] = 5; // 分配索引远大于数组长度的属性 fruits.age = 25; // 创建一个具有任意名称的属性 复制代码
声明
一个好习惯:在创建数组或对象的时候,以逗号结尾 便于添加和删除
let fruits = [ "Apple", "Orange", "Plum", ]; 复制代码
方法汇总
增加移除
push 后插
pop 弹出最后一个
shift 前删,有返回值 即该元素
unshift 在第一个添加
splice 可以添加、删除和插入
arr.splice(start[, deleteCount, elem1, ..., elemN])
从索引start开始,删除n个元素
如果只填start,该索引以后的全部删除
返回值是删除元素组成的数组
slice 切片/截取操作
arr.slice([start], [end])
左开右闭
返回新数组
不带参数返回副本
concat 连接操作
参数可以是值或数组
在数组中搜索
indexOf / lastIndexOf / includes
arr.indexOf(item, from)
从索引from
开始搜索item
,如果找到则返回索引,否则返回-1
。arr.lastIndexOf(item, from)
—— 和上面相同,只是从右向左搜索。arr.includes(item, from)
—— 从索引from
开始搜索item
,如果找到则返回true
(译注:如果没找到,则返回false
)。find 和findIndex
filter
find 返回第一个满足的情况,如果需要多个可以使用 filter
转换数组
map
对数组每个元素都调用函数,并返回结果数组。返回新值而不是当前元素
sort 原位排序
默认按照字符串进行排序
如果想要按整数值进行排序,就为sort函数提供一个排序规则的函数
比较函数 返回值大于1,升序。否则降序
reverse 颠倒顺序
split 将字符串通过指定分隔符分割成数组
join 数组指定分隔符连接成字符串
reduce
一个接一个地应用于所有数组元素,并将其结果“搬运(carry on)”到下一个调用。
accumulator
—— 是上一个函数调用的结果,第一次等于initial
(如果提供了initial
的话)。item
—— 当前的数组元素。index
—— 当前索引。arr
—— 数组本身。let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((sum, current) => sum + current, 0); alert(result); // 15 复制代码
如果回调函数后面有初始值,则该初始值会作为sum初始值。如果没有初始值,则sum默认等于数组第一个元素,从第二个元素开始迭代
reduceRight 与 reduce 一样,只是遍历从右向左
如何证明一个数组是数组
arr instanceOf Array 返回 true 说明是数组
Array.isArray(value) value是数组的话返回true
性能
毫无疑问 push, pop效率高 shift, unshift效率低
循环
for循环
let arr = ["Apple", "Orange", "Pear"]; for (let i = 0; i < arr.length; i++) { alert( arr[i] ); } 复制代码
for..of
let fruits = ["Apple", "Orange", "Plum"]; // 遍历数组元素 for (let fruit of fruits) { alert( fruit ); } 复制代码
for..in 本来是用来遍历对象的,但数组本质上也是对象。因此也可以用 for..in
let arr = ["Apple", "Orange", "Pear"]; for (let key in arr) { alert( arr[key] ); // Apple, Orange, Pear } 复制代码
但这其实是一个很不好的想法。会有一些潜在问题存在:
for..in
循环会遍历 所有属性,不仅仅是这些数字属性。在浏览器和其它环境中有一种称为“类数组”的对象,它们 看似是数组。也就是说,它们有
length
和索引属性,但是也可能有其它的非数字的属性和方法,这通常是我们不需要的。for..in
循环会把它们都列出来。所以如果我们需要处理类数组对象,这些“额外”的属性就会存在问题。for..in
循环适用于普通对象,并且做了对应的优化。但是不适用于数组,因此速度要慢 10-100 倍。当然即使是这样也依然非常快。只有在遇到瓶颈时可能会有问题。但是我们仍然应该了解这其中的不同。
通常来说,我们不应该用 for..in
来处理数组。
不,我们永远不要用这个
forEach
length
惊了,原来length 是最大索引加一
let fruits = []; fruits[123] = "Apple"; alert( fruits.length ); // 124 复制代码
清空数组建议用 arr.length = 0, 如果直接 arr = [], 实际上是又创建了一个对象,改变了引用而已。原来的数组还在内存中,虽然 JavaScript 有垃圾回收器,但无疑这消耗了性能。
toString
转成字符串逗号隔开
let arr = [1, 2, 3]; alert( arr ); // 1,2,3 alert( String(arr) === '1,2,3' ); // true 复制代码
数组的比较
不要用==比较两个数组,当且进度引用相同时才相等。
let a = [1, 2, 3] let b = [1, 2, 3] a == b false
作者:Chin是我啊
链接:https://juejin.cn/post/7018152781991116807