函数式编程一

函数式编程

  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), {})
			},
		}
原文地址:https://www.cnblogs.com/bridge7839/p/10617699.html