继上一篇 Array.prototype.reduce 后,我立志要好好学习。琢磨了很久,再加上最近看了几篇"JS 函数式编程"的文章和书籍后,然后有感而发写下了这篇文章。

Array.prototype.map 方法相信大家都用的很熟悉了,同时我也相信很多人已经自己实现了 map 函数。没有实现过自己的map ? 没关系,我们先用for 循环来实现下。

  Array.prototype.selfMap = function () {const ary = thisconst result = []const [ fn, thisArg ] = [].slice.call(arguments)if (typeof fn !== 'function') {throw new TypeError(fn + 'is not a function')  }for (let i = 0; i < ary.length; i++) {result.push(fn.call(thisArg, ary[i], i, ary))}return result}const a = new Array(1, 2, 3, 4)a.selfMap(item => item + 1) // [ 2, 3, 4, 5 ]
复制代码

实现了自己的map,还不是美滋滋。

但是,这和本文没有半点关系,因为我是要用reduce实现map啊???

众所周知,map函数需要传一个函数的,还有一个可选的this参数,但是我发现第二个参数大家很少用到,也不怎么注意,我也是这样。

[1, 2, 3].map(function(item) {console.log(this)return item
}, { msg: 'mapping' })
复制代码

上面?这段代码块不仅会返回一个新的数组,还会在控制台打印三次

 { msg: 'mapping' }
复制代码

有图有真相?

可能有的小伙伴在验证我上面的例子时,会使用箭头函数,然后发现总是打印window,就是下面这样?

然后心里暗道“无耻小儿,竟敢骗我”。心里苦啊,箭头函数在声明时就绑定了它外层的this(此例的thiswindow,而且还改变不了, 也就是说{ msg: 'mapping' }相当于白传了)?

似乎废话有点多额,那我们先用reduce来实现map吧(默认运行环境支持Array.prototype.reduce,如果不支持的话,那还写个?)

    // 这次不把方法写在Array的原型上const reduceMap = (fn, thisArg /*真想去掉thisArg这个参数*/ ) => {return (list) => {// 不怎么愿意写下面这两个判断条件if (typeof fn !== 'function') {throw new TypeError(fn + 'is not a function')  }if (!Array.isArray(list)) {throw new TypeError('list must be a Array')}if (list.length === 0) return []return list.reduce((acc, value, index) => {return acc.concat([ fn.call(thisArg, value, index, list) ])}, [])}}// 来使用下怎么样?reduceMap(x => x + 1)([ 1, 2, 3 ]) // [ 2, 3, 4 ]const mapAry1 = reduceMap(function(item) {console.log(this)return item + 1}, { msg: 'mapping' })([ 1, 2, 3 ]) // [ 2, 3, 4 ] // logging { msg: 'mapping' } three times
复制代码

?实现的原理相信大家应该都懂吧。

打铁当趁热,继续来实现filter吧。

  • for 循环实现版
Array.prototype.selfFilter = function () {const ary = thisconst result = []const [ fn , thisArg ] = [].slice.call(arguments)if (typeof fn !== 'function') {throw new TypeError(fn + 'is not a function')  }for (let i = 0; i < ary.length; i++) {if (fn.call(thisArg, ary[i], i, ary)) {result.push(ary[i])}}return result
}const a = new Array(1, 2, 3)
a.selfFilter(item => item % 2 === 0) // [ 2 ]
a.selfFilter(function (item) {console.log(this)return item % 2 === 0
}, {})
// [ 2 ]
// logging {} three times
复制代码
  • reduce 实现版
// 同map, 不定义在Array的原型上
const reduceFilter = (fn, thisAry /* thisAry知不知你好讨厌啊 */ )  => {return (list) => {if (typeof fn !== 'function') {throw new TypeError(fn + 'is not a function')  }if (!Array.isArray(list)) {throw new TypeError('list must be a Array')}if (list.length === 0) return []return list.reduce((acc, value, index) => {return fn.call(thisAry, value, index, list) ? acc.concat([ value ]) : acc}, [])}
}reduceFilter(x => x % 2 === 0)([ 1, 2, 3 ]) // [ 2 ]复制代码

文章里掺杂了些许函数式编程里面的东西,因为我也才开始学函数式编程不久,就不在大佬们面前献丑了。如果文章里有哪里写的不对或者不够准确,亦或者是觉得有写的不好的地方,烦请各位指正,也让我改正。

JS Array.reduce 实现 Array.map 和 Array.filter相关推荐

  1. Array.reduce函数学习(适用大数据)

    文章目录 参考 快速入门 语法 参数说明 例子--数组求和 callback 被调用四次,每次调用的参数和返回值如下表 例子--计算数组中每个元素出现的次数 例子--数组去重 例子--将二维数组转化为 ...

  2. Array.prototype.map() 、 Array.prototype.reduce()、Array.prototype.filter()

    文章目录 1. map 2. reduce 3. filter 1. map   map 函数接收一个回调函数作为参数,然后返回一个数组,这个数组中的每个元素都是调用回调函数后返回的结果.如: fun ...

  3. JS Array.reduce 对象属性累加

    Array reduce 数组对象使用 无非就是 计算数组元素 相加后的总和 ,看网上给的Demo 全是 [1,2,3,4,6].reduce 这种基本用法, 在实际开发中 数组中一般都是放对象 本次 ...

  4. 自从学会了 Array.reduce() ,再也离不开它

    作者简介: 李中凯老师,8年前端开发,前端负责人,擅长JavaScript/Vue. 公众号:1024译站 掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b5800 ...

  5. JS高程5.引用类型(6)Array类型的位置方法,迭代方法,归并方法

    一.位置方法 ECMAScript5为数组实例添加了两个位置:indexOf()和 lastIndexOf().这两个方法接收两个参数:要查找的项和(可选的)表示查找起点位置的索引(如在数组[7,8, ...

  6. 百变星君 Array.reduce

    Vue3 商城项目开源地址:https://github.com/newbee-ltd/newbee-mall-vue3-app Vue3 高仿微信记账本项目开源地址:https://github.c ...

  7. Hadoop 数据类型与文件结构剖析 Sequence, Map, Set, Array, BloomMap Files

    今天要推荐的一篇文章发表在知名云存储提供商 Cloudera 的博客,本文细致且图文并茂地讲解了 Hadoop 的几种典型文件结构及他们之前的关系.NoSQLFan 将主要内容翻译整理如下(如有错漏, ...

  8. js实现数组降维算法[不准用Array.prototype.flat的api]

    js实现数组降维算法[不准用Array.prototype.flat的api] // target要降维的元素,n降维阶数,newArr存储结果的新数组 function f(target, n = ...

  9. js字符串(String)转多维数组(Array) - 代码篇

    js字符串(String)转多维数组(Array) - 代码篇 Demo代码: <!DOCTYPE html> <html> <head> <meta cha ...

最新文章

  1. EasyUI权限系统
  2. typeorm 更新_再热我们也在更新 - Midway 8 月内容汇总
  3. 与计算机组成原理相关论文题目,计算机组成原理论文
  4. 敏捷毒药-敏捷中有损组织整体的负面实践
  5. android listview下拉刷新动画,ListView下拉刷新实现方式详解和改造(上)
  6. Spring jdbc 对象Mapper的简单封装
  7. PowerDesigner 建立约束
  8. 万用表判断场效应管的好坏
  9. cocos2d-x瓦片地图制作详解
  10. qq账号绑定服务器地址,网站接入 QQ 登录整合社交账号登录 - 文章教程
  11. mac英文输入模式下不能长按连续输入
  12. kindle亚马逊个人文档不显示_Kindle个人文档服务
  13. Android文字跑马灯简单实现的三种方法
  14. 进入fastboot模式后,一连接刷机助手就变成press any key to shutdown
  15. krpano 运算符
  16. 自我激励--相信自己,付诸行动
  17. #Java实例(一)
  18. 服务器机器hba卡型号,服务器hba卡需要配置什么
  19. 中央空调如何调节温度html,麦克维尔中央空调设置温度单位方法
  20. 婴幼儿办理护照的过程及注意事项(原创)

热门文章

  1. 例说DNS递归/迭代名称解析原理
  2. cocos2d-x 2.0启用HD高清图片支持
  3. PL/SQL基础篇4(游标)
  4. 【书评】OSPF Anatomy of an Internet Routing Protocol
  5. C语言open和creat函数
  6. 使用libjpeg进行图片压缩(哈夫曼算法,无损压缩)
  7. 五个超酷Linux命令
  8. SQL2000中默认sa帐号改名和删除的最安全方法
  9. LDAP 中 CN, OU, DC 的含义(ldap学习一)
  10. lintcode---线段树查询||(区间元素个数)