• 函数式编程一


    函数式编程

    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), {})
    			},
    		}
    
  • 相关阅读:
    jquery easy ui 学习 (8)basic treegrid
    jquery easy ui 学习 (7) TreeGrid Actions
    jquery easy ui 学习 (6) basic validatebox
    jquery easy ui 学习 (5) windowlayout
    jquery easy ui 学习 (4) window 打开之后 限制操纵后面元素属性
    提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
    visual studio 添加虚线的快捷键
    VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
    visual studio 编译时 出现 Files 的值 乱码
    微信 连接被意外关闭
  • 原文地址:https://www.cnblogs.com/bridge7839/p/10617699.html
Copyright © 2020-2023  润新知