美文网首页让前端飞Web前端之路
javscript 函数式编程库

javscript 函数式编程库

作者: visitor009 | 来源:发表于2020-05-02 07:24 被阅读0次

    下载地址: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 mochawesome
    npm install
    npm run test
    
    // 生成测试报告
    npm run report
    // 生成测试用例规格
    npm run spec
    

    浏览器

    直接打开browserTest/index.html

    使用

    安装

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

    统一

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

    集合(数组或对象)

    数组

    函数

    对象

    实用功能

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

    each each [^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 == 5
    count = 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 // 3
    add2(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-01
    formatDate('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]
    

    相关文章

      网友评论

        本文标题:javscript 函数式编程库

        本文链接:https://www.haomeiwen.com/subject/twuhghtx.html