> 这是我参与新手入门的第2篇文章
前言
javascript数组相信大家都不陌生。在平时学习中,开发项目中大家都会频繁使用数组api,可以说数组在整个javascript的学习过程中尤为重要。我们如果不深入地了解数组,那么很难应付平时的各种需求...
本文将初步带你整理数组眼花缭乱的api,先对数组api有个清晰的认识。同时,在后面几个部分将一起手撕数组扁平化和数组去重,加深对数组api的理解。
怎么判断目标是不是数组呢?
- 思路1:在es6中新增了一个
Array.isArray(arg)方法,能直接判断arg是不是数组。 - 思路2:直接判断
arg是啥类型,之后看是不是数组。那么,怎么判断目标是啥类型呢?Object.prototype.toString.call(arg)能完美判断arg是哪个类型,如果Object.prototype.toString.call(arg) === '[object Array]'那么arg就是数组。 - 思路3:借助原型链判断。这个思路就有很多种方式了,下面给出总结:
1、 Array.isArray(arg) // 思路1
2、 Object.prototype.toString.call(arg) === '[object Array]' // 思路2
//=====以下是思路3======
3、 arg.constructor === Array //这个判断不一定可靠,因为constructor是可以修改的.
4、 Array.prototype.isPrototypeOf(arg) //注意,必须是Array.prototyoe,不能是Array.原因就不用我说了吧
5、 Object.getPrototypeOf(arg) === Array.prototype
6、 arg instanceof Array
数组有哪些改变自身的方法呢?
这里整理了9个会改变自身的方法:
pop()删除数组最后一个元素,并返回这个元素(空数组为undefined)。push(*arg1, ..., argN*)添加元素到数组最后一项,并返回添加元素后的数组长度。shift()删除数组第一项,并更新length。返回删除的第一项的值(空数组为undefined).unshift(*arg1, ..., argN*)添加元素到数组开头,并返回添加元素后的数组长度(插入顺序与参数顺序一样)。reverse()颠倒数组中元素的位置,并返回该数组的引用。sort([*compareFunction(elem1, elem2)*])应用compareFunction进行排序。若没有提供compareFunction,则按照转换为字符的unicode位点进行排序。 具体查看MDN。splice(*start[, deleteCount, arg1, arg2]*)删除数组从start开始之后的deleteCount个元素,然后将arg1,arg2添加进start之后的位置。返回删除元素组成的数组。注意:start可以是负数,若是负数会变成length + start。fill(*value[, start, end]*)用value值替换数组从start下标开始的到end结束的内容。若不提供可选参数,则是替换数组全部内容。返回替换后数组的引用。注意:start可以是负数,若是负数会变成length + start。copyWithin(*target[, start[, end]]*)将数组下标从start开始到end结束的内容浅复制到下标为target位置。注:这是一个高性能的移动数据的方法 。若参数是负数则会变成length + 其值。
数组有哪些不改变自身的方法?
这里整理了几种不改变自身的方法:
concat(*arg1, ..., argN*)用于合并多个数组。返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。 这包括也是数组的数组参数的元素。 还有就是,concat的参数如果既包含数组,也包含普通类型。对于数组来说,也会将其解构再连接,而不是连接整个数组项。slice([begin[, end]])返回一个由原数组begin至end的浅拷贝。同时注意slice()是不改变自身的,而splice()却是改变自身的。includes(*valueToFind[, fromIndex]*)从数组的fromIndex项开始到结尾,判断是否包含valueToFind,返回一个Boolean。需要注意的是,includes可以检查数组中是否有NaN。对于-0和+0是当一回事。相等规则见 MDN:零值相等
4.
indexOf(searchElem[, fromIndex])5.lastIndexOf(searchElem[, fromIndex])返回在数组中从fromIndex到结尾找到的第一个searchElem的索引。若不存在则返回-1。注意:indexOf/lastIndexOf都是使用===来判断searchElem与数组项是否相等的. 6.join(seperator)返回使用seperator将数组的每一项连接成的一个字符串。注意:对于数组项来说,如果值为null或者undefined,再返回结果中则会用空字符串替换
不改变自身的遍历方法
forEach(callBack:(value[, index[, array]])[, thisArg])返回undefined,意味着没办法链式调用。 注意的点有:
(1)、forEach是不改变数组的,但那个数组可能会被callBack改变。
(2)、遇到空项(稀疏数组)会直接跳过。空项并不是指值为null或undefined的,而是指从未被赋值的。
(3)、除了抛出异常以外,没有办法中止或跳出循环。
(4)、forEach遍历的元素范围在第一次调用callBack时就确定了。也就是说在迭代时往数组尾部增加元素是没用的;而若是往数组开头加元素的话,会将各元素index + 1,此时可能会出现重复操作某个元素的情况。删除元素的话,若是删除未迭代的元素则跳过该元素; 若是删除已迭代的元素,那么未迭代的元素将依次index - 1,此时或许会出现跳过元素的情况。every(callBack:(value[, index[, array]])[, thisArg])返回一个Boolen。需要注意的是:
(1)、若是空数组调用这个方法,那么总是返回true。也就是说,若是需要使用every来判断某个数组项时,需要事先排除数组为空的情况。
(2)、every遍历的元素范围在第一次调用callBack时就确定了。
(3)、遇到空项(稀疏数组)会直接跳过。空项并不是指值为null或undefined的,而是指从未被赋值的。
(4)、callBack需要返回一个truthy(可以转换为true)值或falsy(可以转换为false)值。every遍历在第一次遇到callBack返回falsy值时中止并退出循环且返回false。some(callBack:(value[, index[, array]])[, thisArg])测试数组中是不是至少有1个元素通过了被提供的函数测试。返回一个Boolean。需要注意的有:
(1)、若是空数组调用这个方法。则总是返回false。
(2)、遇到空项(稀疏数组)会直接跳过。空项并不是指值为null或undefined的,而是指从未被赋值的。
(3)、some遍历的元素范围在第一次调用callBack时就确定了。filter(callBack:(value[, index[, array]])[, thisArg])其返回一个新数组,其包含原数组所有通过callBack测试的数组项。需要注意的有:
(1)、遇到空项(稀疏数组)会直接跳过。空项并不是指值为null或undefined的,而是指从未被赋值的。
(2)、filter遍历的元素范围在第一次调用callBack时就确定了。map(callBack:(value[, index[, array]])[, thisArg])返回一个新数组,新数组的每一项都是原数组经过callBack变换而来的。需要注意的有:
(1)、遇到空项(稀疏数组)会直接跳过。空项并不是指值为null或undefined的,而是指从未被赋值的。
(2)、map遍历的元素范围在第一次调用callBack时就确定了。
(3)、原数组的空项也会保留在新数组当中。reduce(callBack:(accumulator[, value[, index[, array]]])[, initialValue])返回函数累计器处理的结果。需要注意的是:
(1)、若调用reduce的数组是空数组且没有提供initialValue.则会抛出TypeError.
(2)、如果没有提供initialValue,那么accumulator会取数组第一项的值,且从第二项(索引为1)开始调用callBack。所以如果数组只有一项,且没有initialValue,则不会执行callBack. 7.reduceRight()与reduce相比,取最后一项find()findIndex()这两个与前面的不同:
(1)、其不会跳过空项.
(2)、被删除的元素依旧能访问到,但其值为undefined
总结:
本文章介绍了:
判断目标是不是数组的6中方式。(还记得是哪6种不?-。-)
数组改变自身的9个方法:
push,pop,shift,unshift, reverse,sort,splice, fill, copyWithin.
其中:
- 可以删除元素的方法都返回删除元素(的集合),而splice不管删除多少个都是返回数组,若是指提供start参数不提供deleteCount参数,则返回原数组。
- 增加元素的方法都是返回增加元素的数组的长度
- 不增加也不删除的方法返回操作后原数组的引用
数组不改变自身的6个非遍历方法:
concat,slice,includes,indexOf,lastIndexOf,join
数组不改变自身的9个遍历方法:
forEach,every,some,filter,map,reduce,reduceRight,find,findIndex
其中: - 除了reduce/reduceRight外,其他的遍历方法都有一个可选thisArg参数。在传递thisArg参数时需要注意:
- callBack不能是箭头函数,不然不然thisArg是什么,都会指向全局对象(window)
- 若是传递的thisArg为null或者undefined,则会用window替换thisArg
- forEach, every, some,filter,map都会:
- 跳过空项元素.
- 遍历范围都在第一次调用callBack时就确定
还有就是,本文章介绍的所有数组方法都是通用型的。也就是说可以通过方法借用使得类数组对象也能使用这些方法...
对于方法涉及下标的,若是下标为负数,则会用length + index替换.
觉得不错就点个赞吧~