美文网首页
函数式编程笔记(JavaScript描述)

函数式编程笔记(JavaScript描述)

作者: 罗坤_23333 | 来源:发表于2018-09-13 16:37 被阅读0次

    特性概览

    • 函数是“第一等公民”
      函数和其他数据类型一样,处于平等地位,可以赋值给其他变量,可以作为参数,可以作为其他函数的返回值
    • 只用“表达式”,不用“语句”
      “表达式”是一个单纯的运算过程,总有返回值,“语句”是执行某种操作,没有返回值
    • 没有副作用,不修改状态
      函数式编程只返回新的值,不修改系统变量

    目录

    1. 纯函数(pure function)
    2. 柯里化
    3. 函数的合成
    4. 高阶函数
    5. 回调
    6. 递归
    7. 立即执行函数
    8. 惰性函数
    9. 偏函数

    纯函数

    • 一个函数的返回结果只依赖与它的参数
      var a = 1;
      function func(b){
        return a +b;
      }
      
      func(2); // 3
      a = 2;
      func(2); // 4
      //func受到外部变量影响了
      
      // 修正
      function func(a, b){
        return a+b
      }
      
    • 在执行过程中没有副作用
      var obj = { age: 1 }
      function func(obj, b){
        obj.age += 1;
        return obj.age + b;
      }
      
      func(obj, 1);
      console.log(obj); // { age: 2 } 外部变量obj被篡改了
      
       //修正
      function func(obj, b){
       var age = obj.age + 1;
       return age + b;
      }
      

    柯里化

    柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术

    //柯里化之前
    function add(x,y){
        return x+y
    }
    add(1,2)    //3
    //柯里化之后
    function addC(x){
        return function(y){
            return x+y
        }
    }
    addC(1)(2)  //3
    

    柯里化通用实现前端开发者进阶之函数柯里化Currying

        function currying(fn){
            var slice = Array.prototype.slice,
            _args = slice.call(arguments,1)
            return function(){
                var _inargs = slice.call(arguments)
                return fn.apply(null, _args.concat(_inargs))
            }
        }
    

    链式调用函数

    const compose = function(f){
        return function(g){
            return function(x){
                return f(g(x))
            }
        }   
    }
    compose(f)(g)(x)
    //链式调用函数
    

    函数的合成

    高阶函数

    函数可以作为参数被传递
    常见于回调函数callback,也称函数传递

    var getUserInfo = function(userId,callback){
        $.ajax(url+userId,function(data){
            if(typeof callback === 'function'){
                callback(data)
            }
        })
    }
    //使用
    getUserInfo(13157,function(data){
        console.log(data)
    })
    

    PS:Array.prototype.sort也接受函数作为参数,还有each,filter等等

    函数可以作为返回值输出
    单例模式初探版

    var getSingle = function(fn){
        var ret;
        return function(){
            return ret || (ret = fn.apply(this,arguments))
        }
    }
    

    回调

    封装一个Function.prototype.method,让它看起来像回调函数。

        Function.prototype.method = function(name, func){
            if(!this.prototype[name]){
                this.prototype[name] = func
            }
            return this;
        }
        
        // 使用
        // 判断数字的正负
        Number.method('integer', function(){
            return Math[this < 0 ? 'ceil' : 'floor'](this)
        })
        
        // 移除字符串首尾空白的方法
        String.method('trim', function(){
            return this.replace(/^\s+|\s+s/g, '')
        })
    

    递归

    斐波那契数列

    //一共10级楼梯,每次可以走一步或两步,求一共多少种走法。
    //公式:f(n)=f(n-1)+f(n-2)
    
      function f(n){
          if(n==1){
              return 1
          }else if(n==2){
              return 2
          }else {
              return f(n-1)+f(n-2)
          }
      }
    

    尾递归

      function fibonacci(n){
            function _fibonacci(n,n1,n2){
                if(n <=1){
                    return n2
                }
                return _fibonacci(n,n2,n1+n2)
            }
            
            return _fibonacci(n,1,1)
        }
    

    在ES6中尾递归可以这样写,不过需要在'use strict'模式下

       'use strict'
       function fibonacci(n, n1 = 1, n2 = 1){
            if(n<=1) return n2
            return fibonacci(n, n2, n1+n2)
        }
    

    立即执行函数

    IIFE

      ;(function(data){
        console.log(data)    //asd
      })('asd');
    
      (function(global){
        console.log(global)    //window
        //构造函数
        function Set(){
            this._values = []
        }
        Set.prototype['log'] = function(){console.log(this._values)}
        global.Set = Set;
      })(this)
      //使用
      var set = new Set()
      set.log()    //[]
    

    惰性函数

    惰性函数(lazy-functions)就是解决每次都要进行判断的这个问题,解决原理很简单,重写函数
    实例:兼容现代浏览器与IE的addEvent事件
    一般写法

      function addEvent(type, el, fn) {
            if(window.addEventListener){
                el.addEventListener(type, fn, false)
            }
            else if(window.attachEvent){
                el.attachEvent('on'+type, fn)
            }
        }
    

    惰性函数写法

      function addEvent(type, el ,fn){
            if(window.addEventListener){
                addEvent = function(type, el ,fn){
                    el.addEventListener(type, fn, false)
                }
            }
            else if(window.attachEvent){
                addEvent = function(type, el ,fn){
                    el.attachEvent('on'+type, fn)
                }
            }
        }
    

    偏函数

    JavaScript专题之偏函数
    什么是偏函数:固定函数的第一个或几个参数,返回一个新函数,接收剩下的参数。
    英语:partial,又称局部应用bind()就是典型的偏函数

    function add(a, b) {
        return a + b;
    }
    
    var addOne = add.bind(null, 1);
    
    addOne(2) // 3
    

    相关文章

      网友评论

          本文标题:函数式编程笔记(JavaScript描述)

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