javscript 函数式编程库

作者 : 开心源码 本文共8785个字,预计阅读时间需要22分钟 发布时间: 2022-05-13 共127人阅读

下载地址:gitee

javascript 函数式编程的接口库

模仿underscore.js实现自己的函数库,添加额外自己常用的函数,用于学习函数式编程

  • 使用es6实现部分underscore.js的函数,添加自己常用的
  • 添加自己常用到的函数,如onceDelay(运行一次后在指定时间后才能再次运行)
  • 错误解决:
    • 指定参数类型才能运行函数
    • 检测运行时函数能否为必需,必需时没传函数控制台输出提醒信息
  • 单元测试

目录结构

+ browserTest // 浏览器单元测试环境    |-- index.html+ lib    |-- functional.js // 函数库  + mochawesome-report    |-- mochawesome.html // 单元测试报告+ doc 文档    |-- index_with_tree+ test 单元测试    |-- functional.test.js // 测试用例代码    |-- spec.html // 测试用例规格  

运行单元测试

node

npm install -g mocha mochawesomenpm installnpm run test// 生成测试报告npm run report// 生成测试用例规格npm run spec

浏览器

直接打开browserTest/index.html

使用

安装

  • 浏览器: 通过<script>引入,默认绑定全局变量 _
  • node: require 引入

统一

  • 传入 [context],在function中的this会指向[context]
  • 当传入不合符函数的参数类型时,会返回自身(有想过返回undefined),不会去运行函数
  • 当函数参数中 function 为必传时,没传控制台会输出提醒信息
  • 参数带 [ ] 为选填,如[context]

集合(数组或者对象)

  • each
  • map
  • reduce
  • find
  • filter
  • every
  • some
  • max
  • min
  • contains
  • size
  • isEmpty

数组

  • last
  • unique
  • range

函数

  • partial
  • memoize
  • curry
  • delay
  • throttle
  • debounce
  • once
  • pipe

对象

  • hasKey
  • isEqual
  • inMatch
  • isObject
  • isArray
  • isFunction
  • isPromise
  • isDate
  • isRegExp
  • isMap
  • isSet
  • isString
  • isNumber
  • isNull
  • isNaN
  • isUndefined
  • isSymbol

实用功能

  • random
  • formatDate
  • noConflict
  • checkValueType
  • deepClone

<h2 name=’集合’>集合 (数组或者对象)</h2集合>

each

_.each(list, function, [context]) 遍历集合中的每一个元素。 list可以是 Object|Array|String|Set|Map,function 的参数是(value, key, list)

_.each([1,2],(value,key,list)=>{    console.log(value,key,list) // 1 0 [1,2]})

<h4 name=’map’>map</h4>

_.map(list, function, [context]) 将集合中的每一个元素转换成function的返回值,返回值是原来的数据类型。 list可以是 Object|Array,function 的参数是(value, key, list)

_.map([1,2],value=>value+1) // [2,3]_.map({a:2,b:3},value=>value+1) // {a:3,b:4}

<h4 name=’reduce’>reduce</h4>

_.reduce(list, function, [context]) 迭代集合中的元素,将每次迭代的值保存在memo参数中。 list可以是 Object|Array|String,function 的参数是(memo,value, key, list)

_.reduce([1,2,3],(memo,value)=>value+memo) // 6 _.reduce({a:2,b:3},(memo,value)=>value+memo) // 5_.reduce('str',(memo,value)=>value+'-'+memo) // s-t-r

<h4 name=’find’>find</h4>

_.find(list, function, [context]) 在集合查找符合function 返回值的元素。 list可以是 Object|Array|String,function 的参数是(value, key, list)

_.find([1,2,3],value=>value === 3) // 3 _.find({a:2,b:3},value=>value === 3) // 3_.find([{a:2},{a:3}],obj=>obj.a === 3) // {a:3}_.find('str',value=>value == 't') // t

<h4 name=’filter’>filter</h4>

_.filter(list, function, [context]) 返回在集合中符合function 返回值的元素。 list可以是 Object|Array,function 的参数是(value, key, list)

_.filter([1,2,3],value=>value >= 2) // [2,3] _.filter({a:2,b:3},value=>value === 3) // {b:3}

<h4 name=’every’>every</h4>

_.every(list, function, [context]) 在集合中每一项元素都符合条件,返回true。 list可以是 Object|Array|String,function 的参数是(value, key, list)

_.every([1,2,3],value=>value != 0) // true_.every([1,2,3],value=>value >= 2) // false_.every({a:2,b:3},value=>value != 0) // true_.every('sss',value=>value == 's') // true

<h4 name=’some’>some</h4>

_.some(list, function, [context]) 在集合中每一项元素都符合条件,返回true。 list可以是 Object|Array|String,function 的参数是(value, key, list)

_.some([1,2,3],value=>value == 0) // false_.some([1,2,3],value=>value == 2) // true_.some({a:2,b:3},value=>value != 0) // true_.some('str',value=>value == 's') // true

<h4 name=’max’>max</h4>

_.max(list) 返回集合中最大的元素。 list可以是 Object|Array,只支持数字

_.max([1,2,3]) // 3_.max({a:1,b:2}) // 2_.max({}) // undefined

<h4 name=’min’>min</h4>

_.min(list) 返回集合中最大的元素。 list可以是 Object|Array,只支持数字

_.min([1,2,3]) // 1_.min({a:1,b:2}) // 1_.min({}) // undefined

<h4 name=’contains’>contains</h4>

_.contains(list,ele) 包含指定元素,返回true。 list可以是 Object | Array | String, ele可以是 Object | Array | String | Number | Boolean | null | undefined | NaN。注意当是Object | Array 会使用 isEqual 进行判断

_.contains('st','t') // true_.contains({a:1,b:2},2) // true_.contains([1,2],2) // true_.contains([{a:1}],{a:1}) // true

<h4 name=’size’>size</h4>

_.size(list) 返回元素长度。 list可以是 Object | Array | String

_.size('st') // 2_.size({a:1,b:2}) // 2_.size([1,2,3]) // 3

<h4 name=’isEmpty’>isEmpty</h4>

_.isEmpty(list) 集合能否为空 。 list可以是 Object | Array | String

_.isEmpty('st') // false_.isEmpty({a:1,b:2}) // false_.isEmpty([]) // true

<h2 name=’数组’>数组</h2>

<h4 name=’last’>last</h4>

_.last(list) 返回数组最后的元素。

_.last([2,3,1]) // 1

<h4 name=’unique’>unique</h4>

_.unique(list) 数组去重

_.unique([2,3,1,1]) // [2,3,1]

<h4 name=’range’>range</h4>

_.range([start],end,[step]) 生成数组

_.range(4) // [0,1,2,3]_.range(1,4) // [1,2,3]_.range(2,8,2) // [2,4,6]

<h2 name=’函数’>函数</h2>

<h4 name=’partial’>partial</h4>

_.partial(fn,args) 偏函数。使用null为占位符,保存已有参数,返回一个函数,

function add(a,b) {return a+b}let add2 = _.partial(add,null,2) add2(3) // 5

<h4 name=’memoize’>memoize</h4>

_.memoize(fn) 缓存函数运行后的结果。假如缓存中已有,则直接返回。只支持单个参数的函数

let factorial = _.memoize(function (n) {        let result = 1;        return _factorial(n);        function _factorial(n) {            count++; // 调用次数            result *= n;            if (n == 1) {                return result;            }            return _factorial(--n) // es6的尾调用优化        }});let count = 0; // 调用factorial次数factory(5) // 120,count == 5count = 0;factory(5) // 120, count == 0

<h4 name=’curry’>curry</h4>

_.curry(fn,args) 柯里化。将函数变成一元函数(单个参数)的过程。用处:根据一个模板函数,生成多个函数。注意 fn参数中有es6 …rest 无法进行柯里化

function add(a,b) {    return a+b;}let three = _.curry(add)(1,2);let add2 = _.curry(add)(2);three // 3add2(1) // 3

<h4 name=’delay’>delay</h4>

_.delay(fn,delay,[*args]) 推迟运行。args为fn的参数,可以多个

_.delay(alert,1000,'hello')

<h4 name=’throttle’>throttle</h4>

_.throttle(fn,[delay]) 节流函数。在 delay ms内不停触发只运行一次,默认200ms。返回一个函数

let fn = _.throttle(alert,100);window.onmousemove = function() {fn('hello')} // hello

<h4 name=’debounce’>debounce</h4>

_.debounce(fn,[wait]) 防抖函数。运行一次后过 wait ms后才能运行。返回一个函数

let fn = _.debounce(alert,500);window.onmousemove = function() {fn('hello')} // hello

<h4 name=’once’>once</h4>

_.once(fn,[context]) 页面生命周期内只运行一次fn。

let fn = _.once(alert)fn('once')

<h4 name=’pipe’>pipe</h4>

_.pipe(*function) 管道函数。从左往右运行,返回最后函数运行的值

let mapAbs = array=>{    return _.map(array,value=>Math.abs(value))}let max = array=>{    return Math.max(...array)}let fn = _.pipe(mapAbs,max)// let fn = _.pipe(mapAbs ,_.tap((v)=>{log(v)}),max) · // 可用_.tap 调试运行过程的值fn([1,-3,2]) // 3

<h2 name=’对象’>对象</h2>
<h4 name=’hasKey’>hasKey</h4>

_.hasKey(obj,key) obj能否有key 这个属性。

_.hasKey({a:1},'a') // true_.hasKey({},'a') // false

<h4 name=’isEqual’>isEqual</h4>

_.isEqual(obj,other) 判断obj,other 能否深度相等。类型可以是 引用类型: Object | Array | Date | DOM元素, 基本数据类型: String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。注意: Array 与顺序有关,Object 与顺序无关。

_.isEqual([],[])  //true_.isEqual({},{})  //true_.isEqual({a:1},{a:1})  //true_.isEqual({b:1,a:2},{a:2,b:1})  //true,Object 顺序无关_.isEqual({a:[1,false]},{a:[1,false]})  //true_.isEqual({a:{a:NaN}},{a:{a:NaN}})  //true_.isEqual([null,'s'],[null,'s'])  //true_.isEqual([[1,2],{a:1}],[[1,2],{a:1}])  //true_.isEqual([1,2],[2,1])  //false

<h4 name=’inMatch’>inMatch</h4>

_.inMatch(obj,properties) 对象 能否包含 properties。相等类型可以是 引用类型: Object | Array | Date | DOM元素, 基本数据类型: String | NUmber | Boolean | Null | undefined | NaN。遇到第一个false会退出。注意: Array 与顺序有关,Object 与顺序无关;Array 和 Object 会使用isEqual进行判断。

_.inMatch({},{})  //true_.inMatch({a:1},{a:1})  //true_.inMatch({b:1,a:{name:1,age:2}},{a:{age:2,name:1}})  //true,Object 顺序无关_.inMatch({},{a:1}) // false

<h4 name=’isObject’>isObject</h4>

_.isObject(obj) obj能否为一个对象

_.isObject({a:1}) // true

<h4 name=’isArray’>isArray</h4>

_.isArray(obj) obj能否为一个数组

_.isArray({a:1}) // true

<h4 name=’isFunction’>isFunction</h4>

_.isFunction(obj) obj能否为一个函数

_.isFunction(()=>{}) // true

<h4 name=’isPromise’>isPromise</h4>

_.isPromise(obj) obj能否为一个Promise 对象

let promise = new Promise((resovle,reject)=>{})_.isPromise(promise) // true

<h4 name=’isDate’>isDate</h4>

_.isDate(obj) obj能否为一个日期对象

_.isDate(new Date()) // true

<h4 name=’isRegExp’>isRegExp</h4>

_.isRegExp(obj) obj能否为一个正则对象

_.isRegExp(/1/) // true

<h4 name=’isMap’>isMap</h4>

_.isMap(obj) obj能否为一个Map对象

_.isMap(new Map()) // true

<h4 name=’isSet’>isSet</h4>

_.isSet(obj) obj能否为一个Set对象

_.isSet(new Set()) // true

<h4 name=’isString’>isString</h4>

_.isString(obj) obj能否为一个字符串

_.isString('') // true

<h4 name=’isNumber’>isNumber</h4>

_.isNumber(obj) obj能否为一个数字

_.isNumber(1) // true

<h4 name=’isNull’>isNull</h4>

_.isNull(obj) obj能否为一个null

_.isNull(null) // true

<h4 name=’isNaN’>isNaN</h4>

_.isNaN(obj) obj能否为一个NaN

_.isNaN(NaN) // true

<h4 name=’isUndefined’>isUndefined</h4>

_.isUndefined(obj) obj能否为一个undefined

_.isUndefined(undefined) // true

<h4 name=’isSymbol’>isSymbol</h4>

_.isSymbol(obj) obj能否为一个Symbol

let symbol = new Symbol('s')_.isSymbol(symbol) // true

<h2 name=’实用功能’>实用功能</h2>
<h4 name=’noConflict’>noConflict</h4>

_.noConflict() 放弃_的引用(在浏览端有效),返回 _ ;

let my = _.noConflict(); // _ is undefined

<h4 name=’formatDate’>formatDate</h4>

_.formatDate(date,format) 格式化日期。假如不传参数,默认当前日期。 ;

let date = new Date('2020/5/1 18:35:5');// 正常用法 _.formatDate(date,'yyyy-MM-dd')// 固定参数重复使用,可用柯里化或者偏函数`_.partial(_.formatDate,date,null)`let formatDate = _.curry(_.formatDate)(date) formatDate('yyyy-MM-dd') // 2020-05-01formatDate('M月d日') // 5月1日/*  yyyy 年  M 月   MM 月 补0  d 日  dd 补0  H 小时  HH 小时 补0  m 分钟  mm 分钟 补0  s 秒   ss 秒 补0*/

<h4 name=’random’>random</h4>

_.random(min,[max]) 返回min – max 的随机数。只有一个参数,返回0- min ;不包括max .

_.random(2); // 0 1_.random(2,4) // 2,3

<h4 name=’checkValueType’>checkValueType</h4>

_.checkValueType(variable) 检测变量类型。

checkValueType([]) // 'array'checkValueType({}) // 'object'checkValueType(Promise) // 'promise'checkValueType(()=>{}) // 'function'checkValueType(/1/) // 'regexp'checkValueType("") // 'string'checkValueType(123) // 'number'checkValueType(true) // 'boolean'checkValueType(undefined) // 'undefined'checkValueType(null) // 'null'checkValueType(undefined) // 'symbol'checkValueType(NaN) // 'NaN'

<h4 name=’deepClone’>deepClone</h4>

_.deepClone(obj) 深拷贝。支持引用类型(Object Array Date)、基本数据类型(String Number Boolean undefined null NaN )

_.deepClone({a:1,b:2}) // {a:1,b:2}_.deepClone([1,2]) // [1,2]
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » javscript 函数式编程库

发表回复