上一篇文章简单的介绍了一下 js 的类型, 以及数组的增删方法. 这一篇文章, 我们一起来看看数组还有哪些用法, 以及在实际工作中我们可以用这些方法来做些什么. 由于其中有部分内容并不常用, 所以我尽量缩小篇幅. 在这篇文章内介绍完大部分的数组方法, 加快我们实现其它数据结构的脚步.
1,concat()
合并数组, 可以合并一个或多个数组. 会按照参数顺序依次合并进想要合并的数组.
- //concat 的参数并不是只能传入数组, 字符串, 数字, 布尔值, 对象等都可以传入.
- var arr = [0,1,2,3,4,5,6];
- var a = "7";
- var b = true;
- var c = {a:1}
- var d = [9,10]
- var newArr = arr.concat(a,b,c,"d",{b:2})
- //[0, 1, 2, 3, 4, 5, 6, "7", true, {a:1}, "d", {b:2}]
需要注意的是, concat 方法会生成一个新的数组, 并不会改变原数组的值. 那么这里还是要说一下, concat 的主要作用在于合并数组! 而且前面也说过, 并不建议在数组中存入不同类型的参数, 所以上面例子合并的参数只是为了测试可以这么做, 但是不要这么做, 到时候会有意想不到的乱子!
2,join()
把所有的数组元素依照分隔符 (也就是参数) 链接成一个字符串. 如果不传入参数则以 "," 逗号分隔. 该方法同样会生成一个新的字符串结果.
- var arr = ["z","a","k","i","n","g"];
- var arrStr = arr.join("-");
- //["z", "a", "k", "i", "n", "g"]
- //z-a-k-i-n-g
3,some()和 every()
some()方法, 会遍历数组中的每个元素, 直到返回 false 结束! 而 every()呢, 与 some()相反, 直到返回 true 结束! 下面简单举两个例子:
- var isEven = function (val) {
- return (val % 2) == 0 ? true : false;
- }
- var nums = [1,2,3,4,5,6,7,8,9,10];
- var judgeA= nums.every(isEven)
- //false
- var judgeB = nums.some(isEven)
- //true
解释一下, 其实简单来说, some 用来判断本数组中是否存在 (至少有一个) 符合传入函数的条件的值, 而 every 则判断是否本数组中每一个值都符合条件.
那么在上面的例子中, some 方法确定数组中存在符合条件的值, 所以返回 true, 后面有没有符合条件的跟我没关系了. 只要找到找一个符合条件的就说明我可以返回 true 了. 如果 some 方法遍历了整个数组还没有找到符合条件的值, 则会遗憾的返回 false.
而 every 方法, 跟 some 方法其实刚好相反. 我只要发现一个不符合条件, 我就高高兴兴的返回 false, 只有在遍历了整个数组元素发现都符合条件, 才会可怜兮兮的返回 true.
如果要记忆区分这两种方法, 其实并不是很难, every(每一个), 说明只有所有都对才算是 true. 而 some(一些), 说明你有一个就行啦, 我就给你返回 true.
4,forEach(),map()和 filter()
敲黑板! 这是重点! 重点!
forEach():
forEach()方法, 它接受一个方法 (function) 作为参数, 该方法中可以有三个参数 (item,index,arr) 分别是调用 forEach 数组中的每一项元素, 每一项元素的下标, 调用 forEach 方法的数组. 该方法会遍历数组中的每一项, 为每一项执行你想做的事, 不更改原数组并且没有返回值. 但是我们可以自己通过数组的索引来修改原来的数组.
- var nums = [1,2,3,4,5,6,7,8,9,10];
- var newNumsB = [];
- var newNumsA = nums.forEach(function (item,index,arr){
- newNumsB.push(item + 100)
- arr[index] = item + 10;
- })
- console.log(nums)
- //[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
- console.log(newNumsB)
- //[101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
- console.log(newNumsA)
- //undefined
forEach 方法并不会改变原数组, 如果你想要操作调用方法所修改后的值, 需要把他重新赋值给一个空数组, 或者, 如果修改原数组是你想要的结果, 那么可以通过匿名函数的第三个参数来获取到原数组从而更改他.
map():
map()方法, 其实简单来说就是一个映射, 但是 map 必须要有返回值, 并且 map 会返回一个新数组. 同样的, map 也可以有三个参数, 跟 forEach 是一样的. 但是, 你却无法向 forEach 那样来通过匿名函数的第三个参数来改变原数组, 因为 map 需要 return!
- var nums = [1,2,3,4,5,6,7,8,9,10];
- var newMapNums = nums.map(function (item,index,arr) {
- console.log(item,index,arr);
- return item * item;
- })
- console.log(newMapNums)
- // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- filter():
还有一个 filter()方法, 也就是 "过滤".filter 会返回一个调用该方法数组的一个子集, 什么意思呢, 就是说 filter 的参数是一个函数, 该函数是用来逻辑判断的 (类似于 every 和 some 的那种判定), 如果判断结果返回 true 或者可以作为 true 值返回, 那么就会成为这个子集中的一个元素. 简单说就是, 你(调用 filter 方法的数组中每一个元素) 是否能通过我 (filter 的 function 方法) 的判定, 如果可以就会成为我 (返回的新数组) 的一员.
- var nums = [1,2,3,4,5,6,7,8,9,10];
- var newNums = nums.filter(function(item,index,arr){
- return item> 5
- })
- console.log(newNums)
- //[6, 7, 8, 9, 10]
这里要注意的是, 原数组仍旧是无法更改的, 跟 map 一样. 因为它有返回值, 是通过返回值来组织新的数组的.
5,reduce()
英文的解释是缩减, 刚好, 咱们 js 中 reduce 方法差不多就是这个意思. 该方法接收一个函数作为累加器, 数组中的每个值 (从左到右) 开始缩减, 最终计算为一个值.
reduce 的参数有点多, 我还是这样写吧 reduce(function(total,item,index,arr){},initalVal). 其中 item,index,arr 我就不说了, 大家都知道是啥. total 是啥呢? initalVal 能猜到是什么么?
- var nums = [1,2,3,4,5,6,7,8,9,10];
- var newNums = nums.reduce(function(total,item,index,arr){
- return total + item*100
- },100)
- console.log(newNums)
- //5600
total 其实就是指你之前所累加的值, 而 initalVal 就是你最初的 total 是多少, 也就是你在即将开始 reduce 方法时初始值是多少(从什么值开始累加), 可以不传或者传为 0. 那我就有点小问题了, reduce 只能做数值的计算么? 能不能加字符串, 布尔值设置数组呢? 咱们来小试一下.
- var strs = ["a","b","c","d","e","f"];
- var newStrs = strs.reduce(function(total,item,index){
- return total + item + "-"
- })
- console.log(newStrs)
- //ab-c-d-e-f-
哎? 竟然会是这样的结果, 那么咱们来看看为什么. 首先咱们没有传 initalVal, 那么就是从 strs 的第一项开始加, total 的第一个值为字符串 "a", 而后面呢我们又 return 了 item + "-", 也就说是从数组的第二项开始得到了我们想要的结果, 最后我们给数组的最后一个元素 "f", 也加上了 "-", 这就是为啥会有这样的结果的原因了. 所以, 如果大家确实一定不得不想要做这样的操作, 请你用 join 方法!
那么, 我们可不可以在数组中加入其它元素呢? 这里不再赘述, 你们要自己去试试噢.
6,toString(), 把数组中所有元素作为字符串输出.
toString 有点类似于 join, 但是 join 是数组方法, toString 却适用于几乎所有的 javascript 对象. 这里不多说, 点一下就好.
7,valueOf()
与 toString 和 join 在数组中的使用方法是一样的, 也同样是返回以逗号分隔的字符串对象.
但是这里不会多说但是会强调, toString 和 valueOf 都不仅仅只是数组的方法, 他们几乎适用于所有的原生 JS 对象. 而且依照对象的不同会有不同的展现形式!
8,indexOf()和 lastIndexOf()
这两个东西不太好解释, 我看看怎么简单说明一下呢~~~.
indexOf 是返回与参数匹配的第一个元素的索引, lastIndexOf 返回与参数匹配的最后一个元素的索引.
- var nums = [0,1,2,3,4,5,6,6,7,"a",9,10,{name:"zaking"},["b","c"]];
- var a = nums.indexOf(7);
- var b = nums.lastIndexOf(7);
- var c = nums.indexOf(6);
- var d = nums.lastIndexOf(6);
- var e = nums.indexOf(100);
- var f = nums.lastIndexOf(100);
- console.log(a,b,c,d,e,f)
- //8 8 6 7 -1 -1
- var x = nums.indexOf("a");
- var y = nums.lastIndexOf("a");
- console.log(x,y);
- //9 9
- var m = nums.indexOf({name:"zaking"});
- var n = nums.lastIndexOf({name:"zaking"});
- console.log(m,n)
- //-1,-1
- var i = nums.indexOf("b");
- var j = nums.indexOf(["b","c"])
- console.log(i,j)
- //-1,-1
其实可以说 indexOf 是从数组的头部开始搜索, 搜索到了匹配的第一个值就停止搜索并返回该值的下标. 而 lastIndexOf 则是从尾部开始, 搜索到了第一个匹配的值就停止并返回该值的下标.
这里有一个令人不容易注意但是却十分容易混乱的事情, 就是, 无论从头还是从尾来搜索数组, 数组的下标计算方式是永远不会变的, 所以, 不要认为从尾部搜索就是尾部的第一个数组元素下标为 0, 不是这样的!
那么再说, 如果搜索的参数在数组中并不存在, 那么则返回 - 1, 两个方法都是一样的.
而且我们还可以从上面的简单测试代码中发现, 这两个方法的参数只适用于基本类型, 如果对数组中的引用类型元素进行索引查找是不可以也通常是不会应用的!
那么这篇文章就到这里了, 简单介绍了 ES5 数组的几乎所有的方法, 其实 ES6 对数组进行了不错的扩展并且新增了很多方法, 但是这里不会多说, 因为那样的话又会多出几篇的篇幅, 还有一个原因就是阮一峰大神的 ES6 入门 http://es6.ruanyifeng.com/#docs/array 已经介绍的十分详细, 大家如果有兴趣可以自行查阅. 下一篇文章会介绍一下多维数组 (也就二维三维...) 和数组的简单排序.
最后, 由于本人水平有限, 能力与大神仍相差甚远, 若有错误或不明之处, 还望大家不吝赐教指正. 非常感谢!
来源: https://www.cnblogs.com/zaking/p/8711731.html