前言
近一段时间, 因为项目原因, 会经常在前端对数组进行遍历, 处理, JS 自带的遍历方法有很多种, 往往不加留意, 就可能导致知识混乱的现象, 并且其中还存在一些坑. 前端时间在 ediary 中总结了 JS 原生自带的常用的对数组遍历处理的方法, 分别为: map,forEach,filter, 在讲解知识点的同时, 会类比相识的函数进行对比, 这样会有助于思考方法的利与弊.
一, JS 自带的 map()方法
1. 方法概述
map()方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组
2. 格式说明
var newArray = ["1","2","3"].map(fucntion(e,i,arr){return parseInt(e,10)})
map 中回调函数中的第一个参数为: 当前正在遍历的元素
map 中回调函数中的第二个参数为: 当前元素索引
map 中回调函数中的第三个参数为: 原数组本身
3. 使用说明
3.1 支持 return 返回值;
3.2 return 是啥, 相当于把数组中的这一项变为啥(并不影响原来的数组, 只是相当于把原数组克隆一份, 把克隆的这一份数组中的对应项改变了)
3.3 map 只能对元素进行加工处理, 产生一个新的数组对象. 而不能用它来进行筛选(筛选用 filter), 为什么不能, 看个例子就知道了:
4. 例子
4.1 在字符串中使用
在一个 String 上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组
- var map = Array.prototype.map
- var a = map.call("Hello World", function(e){
- return e.charCodeAt(0);
- })
- // a 的值为[72,101,108,108,111,32,87,111,114,108,100]
5. 易犯错的点
5.1 很多时候, map 给回调函数传的是一个值, 但是也有可能传 2 个, 3 个值, 例如下面的例子
- var map = Array.prototype.map
- var a = map.call("Hello World", function(e){
- return e.charCodeAt(0);
- })
- // a 的值为[72,101,108,108,111,32,87,111,114,108,100]
为什么会这样, 因为 parseInt 就是一个函数, 它就是作为 map 的一个回调函数, parseInt 接收两个参数, 一个是 String, 一个是进制
上面的函数就可以化为:
["1","2","3"].map(parseInt(string, radix));
即
- ["1","2","3"].map(function(string, radix){
- return parseInt(string, radix)
- })
- // 所以才返回结果为:[1, NaN, NaN]
6. 与 map 相关
6.1 Map 对象
es6 提供一个对象 Map, 看看这个 Map 建的对象到底是啥东西
它是一个对象, size 是它的属性, 里面的值封装在 [[Entries]] 这个数组里面
- myMap.set(1, "a"); // 相当于 java 的 map.put();
- myMap.set(2, "b");
- myMap.set(3, "c");
- myMap.size();
- myMap.get(1);
- myMap.get(2);
- myMap.get(3);
二, JS 自带的 forEach()方法
1. 方法概述
forEach()方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组
2. 格式说明
forEach 方法中的 function 回调有三个参数,
第一个参数为: 当前正在遍历的元素
第二个参数为: 当前元素索引
第三个参数为: 原数组本身
[].forEach(function(value, index, array))
3. 使用说明
3.1 这个方法没有返回值, 仅仅是遍历数组中的每一项, 不对原来数组进行修改
但是可以自己通过数组索引来修改原来的数组
3.2 forEach()不能遍历对象, 可以使用 for in
4. 缺点
4.1 您不能使用 break 语句中断循环, 也不能使用 return 语句返回到外层函数
4.2 ES5 推出的, 实际性能比 for 还弱
5. 例子
5.1 通过数组索引改变原数组
- var obj = [1,2,3,4,5,6]
- var res = obj.forEach(function(item, index, arr) {
- arr[index] = item * 10;
- })
- console.log(res); // --> undefined
- console.log(obj); // --> [10,20,30,40,50,60]
5.2 如果数组在迭代的时候被修改, 则当前元素与前面的元素会跳过. 因为 forEach()不会在迭代之前创建数组的副本
- var words = ['1', '2', '3', '4'];
- words.forEach(function(Word) {
- console.log(Word);
- if (Word === '2') {
- words.shift();
- }
- });
- // 1
- // 2
- // 4
6. 与 forEach 相关
6.1 $.each 与 for in
可遍历数组, 可遍历对象
6.1.1 遍历数组
- var arr = [1,2,3,4,5]
- var res = $.each(arr, function(index, value){
- console.log(index, value);
- })
- console.log(res); // 返回值, 被遍历的函数
6.1.2 遍历对象
- var obj = {name: "psg", age: 22, gender: "male"};
- // for in 遍历
- for(var key in obj) {
- console.log(key, obj[key]);
- }
- // $.each 遍历
- $.each(obj, function(key, value) {
- console.log(key, value);
- })
三, JS 自带的 filter()方法
1. 方法概述
filter()方法是对原数组进行过滤筛选, 产生一个新的数组对象
2. 注意事项
2.1 filter()不会对空数组进行检测(如果对空数组进行筛选, 返回值位 undefined)
2.2 filter()不会改变原始数组
2.3 返回数组, 包含了符合条件的所有元素. 如果没有符合条件的元素则返回空数组
3. 格式说明
forEach 方法中的 function 回调有三个参数,
第一个参数为: 当前正在遍历的元素
第二个参数为: 当前元素索引
第三个参数为: 原数组本身
[].filter(function(value, index, array), thisValue)
4. 例子
4.1 在一个 Array 中, 删除偶数, 只保留奇数
- var arr = [1, 2, 3, 4, 5, 6, 9, 10, 15];
- var r = arr.filter(function(x) {
- return x % 2 !== 0;
- });
- r; // [1,3,5,9,15]
4.2 把一个 Array 中的空字符串删掉
- var arr = ['A', '','B', null, undefined,'C',' '];
- var r = arr.filter(function(e) {
- return s && s.trim(); // 注意: IE9 一下的版本没有 trim()方法
- });
- r; // ['A', 'B', 'C']
4.3 巧妙去除 Array 的重复元素
- var r, arr = ['A', 'B', 'C', 'D', 'B', 'A']
- r = arr.filter(function(e, i, self) {
- return self.indexOf === i;
- })
- console.log(r); // --> ['A', 'B', 'C', 'D']
4.4 筛选素数
- function get_primes(arr) {
- var i;
- return arr.filter(function (element) {
- var flag = true;
- if (element < 2) {
- flag = false;
- } else {
- for (var i = 2; i < element; i++) {
- if (element % i == 0) {
- flag = false;
- break;
- }
- }
- }
- return flag;
- })
- }
最后
为了帮助大家让学习变得轻松, 高效, 给大家免费分享一大批资料, 帮助大家在成为全栈工程师, 乃至架构师的路上披荆斩棘. 在这里给大家推荐一个前端全栈学习交流圈: 866109386. 欢迎大家进群交流讨论, 学习交流, 共同进步.
当真正开始学习的时候难免不知道从哪入手, 导致效率低下影响继续学习的信心.
但最重要的是不知道哪些技术需要重点掌握, 学习时频繁踩坑, 最终浪费大量时间, 所以有有效资源还是很有必要的.
最后祝福所有遇到瓶疾且不知道怎么办的前端程序员们, 祝福大家在往后的工作与面试中一切顺利.
来源: http://www.qdfuns.com/article/51070/8161f58b37ec8cd9e76256f48318e2b5.html