纯函数

JavaScrip高级教程 · 279 字

  • 相同的输入值,有相同的输出值
  • 输入和输出值以外的其他隐藏信息或状态无关,也与I/O设备产生的外部输出无关。(例如与全局变量无关)
  • 不能有语义上可观察的副作用,例如函数内部进行“触发事件”操作等
    简单总结:
  • 确定的输出产生确定的输出
  • 函数执行时不产生副作用
    副作用:执行一个函数时,除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者外部存储。
    React要求组件要像一个纯函数一样
    配图

函数柯里化

  • 把接受多个参数的函数,编程接受单一参数的函数,并且返回接受余下参数书的新函数的技术;
  • 只传递给函数一部分参数来调用它,并让它返回一个新函数来处理剩余的参数。
function foo(m, n, x, y){
	return m + n + x + y;
}
foo(10, 20, 30, 40);
// 柯里化过程
function bar(m){
	return function(n){
		return function(x){
			return function(y){
				return m + n + x + y;
			}
		}
	}
}
bar(10)(20)(30)(40);
// 简化柯里化
var bar2 = m => n => x => y => {
	return m + n + x + y;
}
bar2(10)(20)(30)(40);

柯里化的函数

符合单一职责原则,一个函数只处理一个功能

逻辑复用

例:打印日志信息的函数

var log = date => type => message => {
	console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`);
}
var nowAndDebugLog = log(new Date())("DEBUG);
var nowAndFetureLog = log(new Date())("FETURE);									 

自动柯里化函数的实现

function myCurrying(fn){
	function curried(...args){
		if(args.length >= fn.length){
			return fn.apply(this, args);
		} else {
			return function(...args2){
				return curried.apply(this, [...args, ...args2])
			}
		}
	}
	return curried;
}

组合函数

概念的理解

对于多个数据都需要多个函数依次调用的情况,考虑设计组合函数进行简化。
例如:一系列数字,均需要先×2再平方,则可以设计如下的组合函数

function composeFn(m, n) {
	return function(count) {
		return n(m(count))
	}
}
var newFn = composeFn(double, square);

通用组合函数的实现

function myCompose(...fns) {
	var length = fns.length;
	for(var i = 0; i < length; i++){
		if(typeof fns[i] !== 'function'){
			throw new TypeError('Expected arguments are all functions!');
		}
	}
	return function(...args){
		var index = 0;
		var result = length ? fns[index].apply(this, args) : args;
		while(++index < length){
			result = fns[index].call(this, result);
		}
		return result;
	}
}