zoukankan      html  css  js  c++  java
  • 函数式编程一

    函数式编程

    1. 纯函数: 不要在函数里直接使用全局变量,这会成为这个函数的隐试依赖, 如果有需要就从参数里传进去
    2. 相同的输入,总是能得到相同的输出. 无副作用.
    3. 有副作用的地方比如操作dom节点, 发起请求等.单独使用一个函数抽出来. 不要和别的纯函数放在一起.
    4. 严格的控制输入,输出的数据类型. 尽量保证输入,输出的值的数据类型是稳定的
    5. 管道函数: 将数据的处理过程分割成一个个小函数用pipe组合起来;
    6. 将复杂的流程分割, 把分支逻辑用curry函数组合;

    柯里化函数的使用场景

    柯里化函数就像手机一样. 遇到它之前觉得没什么. 遇到它之后就再也离不开了.
    柯里化函数的使用场景一般来说有两种.
    1. 函数的参数本身就具有逻辑复杂度.用柯里化包装复杂参数复用代码.
    2. 高阶函数. 函数的参数是预先确定好的. 但是我们需要添加参数来使函数更有复用性.
    

    函数的参数本身就具有逻辑复杂度

    我们想要验证一串数字是否是正确的手机号和邮箱号
    
    	function checkPhone(phoneNumber) {
    	    return /^1[34578]d{9}$/.test(phoneNumber);
    	}
    	function checkEmail(email) {
    	    return /^(w)+(.w+)*@(w)+((.w+)+)$/.test(email);
    	}
    
    
    可能会遇到验证身份证号,验证密码等各种验证信息,因此在实践中,为了统一逻辑,,我们就会封装一个更为通用的函数,将用于验证的正则与将要被验证的字符串作为参数传入
    
    	function check(targetString, reg) {
    	    return reg.test(targetString);
    	}
    
    但是这样封装之后,在使用时又会稍微麻烦一点,因为会总是输入一串正则
    
    	check(/^1[34578]d{9}$/, '14900000088');
    	check(/^(w)+(.w+)*@(w)+((.w+)+)$/, 'test@163.com');
    
    那么这个时候,我们就可以借助柯里化,在check的基础上再做一层封装,以简化使用
    
    	var _check = createCurry(check);
    
    	var checkPhone = _check(/^1[34578]d{9}$/);
    	var checkEmail = _check(/^(w)+(.w+)*@(w)+((.w+)+)$/);
    	checkPhone('183888888');
    	checkEmail('xxxxx@test.com');
    

    高阶函数

    在我们日常的开发中, 高阶函数的使用是已经相当频繁了. ajax的回调函数. 各种事件的回调函数. 特别是在进行函数式编程中各式各样的回调函数比如pipe.
    在这些高阶函数中. 有一些是公共方法. 我们没办法修改他们传入的参数. 而如果此时我们的函数又需要添加参数用来增加复用性式. 柯里化函数就有了用武之地.
    
    比如有两个ajax请求. 
    
    $.ajax({
    	url: "url1"
    	success: function(data) {
    		var type = "url1"
    		console.log(type, data)
    	}
    })
    $.ajax({
    	url: "url2"
    	success: function(data) {
    		var type = "url2"
    		console.log(type, data)
    	}
    })
    
    在这两个ajax请求中他们的回调函数是相似的. 只有变量type不同其他都相同. 但是因为回调函数的参数是一定的. 我们没办法把type从参数里穿进去.我们可以写两个函数.但是这样我们修改的时候就要两个一起改 我们也可以把 type='url1'和 type="url2". 封装到两个函数中. 其他相同的部分封装到一个函数中. 但是这样我们就平白多出了两个函数. 这时我们就可以把回调变成柯里化函数.
    
    var callback = curry(function(type, data) {
    	console.log(type, data)
    })
    $.ajax({
    	url: "url1",
    	success: callback("url1"),
    })
    $.ajax({
    	url: "url2",
    	success: callback("url2"),
    })
    

    pipe函数的使用场景

    pipe函数在处理数据, 表单验证时, 效果非常好
    
    var data = {
        result: "SUCCESS",
        interfaceVersion: "1.0.3",
        requested: "10/17/2013 15:31:20",
        lastUpdated: "10/16/2013 10:52:39",
        tasks: [
            {id: 104, complete: false,            priority: "high",
                      dueDate: "2013-11-29",      username: "Scott",
                      title: "Do something",      created: "9/22/2013"},
            {id: 105, complete: false,            priority: "medium",
                      dueDate: "2013-11-22",      username: "Lena",
                      title: "Do something else", created: "9/22/2013"},
           
        ]
    };
    
    var fetchData = function () {
      return Promise.resolve(data);
    };
    
    var getIncompleteTaskSummaries = function(membername) {
      return fetchData()
        .then(R.prop('tasks'))
        .then(R.filter(R.propEq('username', membername)))
        .then(R.reject(R.propEq('complete', true)))
        .then(R.map(R.pick(['id', 'dueDate', 'title', 'priority'])))
        .then(R.sortBy(R.prop('dueDate')));
    };
    

    常用的函数式编程方法

    		{
    			curry : function(func, numArgs) {
    	            numArgs = numArgs || func.length;
    	            function subCurry(prev) {
    	                return function() {
    	                    var funcArgs = Array.prototype.slice.apply(arguments)
    	                    var args = prev.concat(funcArgs);
    	                    if (args.length < numArgs) {
    	                        return subCurry(args)
    	                    } else {
    	                        return func.apply(null, args);
    	                    }
    	                }
    	            }
    	            return subCurry([]);
    	        },
    			pipe : function() {
    				var funcArr = [].slice.apply(arguments);
    				return function(data) {
    					return funcArr.reduce(function(res, fn) {
    						return fn(res)
    					}, data)
    				}
    			},
    			prop: function(str, obj) {
    				return obj[verity.isString(str)];
    			},
    			propEq: function(prop, val, obj) {
    				return obj[verity.isString(prop)] === val;
    			},
    			pick: function(arr, obj) {
    				return verity.reduce(function(res, prop) {
    					if (obj[prop] !== undefined) {
    						res[prop] = obj[prop] 
    					}
    					return res;
    				}, verity.isArray(arr), {})
    			},
    		}
    
  • 相关阅读:
    Linux下登录Oracle命令行时删除键^H解决方法
    Centos7 根目录存储空间扩展方法
    js取单选按钮,复选按钮的值
    根据地址-地名获取对应的经纬度
    根据中文获得首字母大写————适用于生成编号-流水号
    邮箱格式验证demo
    百度编辑器UEditor,地址栏传值长度有限-在webConfig配置
    基于ASP.Net +easyUI框架上传图片,实现图片上传,提交表单
    Js基础知识-入门
    基础面试题——Javascript
  • 原文地址:https://www.cnblogs.com/bridge7839/p/10617699.html
Copyright © 2011-2022 走看看