函数式思想对代码的优化

柯里化

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

柯里化的简单实现

// 普通的add函数
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

通用的柯里化方法

function curry(func) {
  var fixedArgs = [].slice.call(arguments,1);
  return function() {
    args = fixedArgs.concat([].slice.call(arguments))
    return func.apply(null, args);
  };
}

柯里化的好处

  1. 参数复用
  2. 提前确认
  3. 延迟运行

惰性求值

惰性求值的定义

对于一个表达式,在不需要值的时候不计算,需要的时候才计算。

JavaScript 并非从语言层面就支持这样的特性,而是要通过一些技术来模拟、实现。
首先,不能是表达式,表达式在 JS 中是立即求值的。所以,将求值的过程包装为函数,只在需要求值的时候才调用该函数。
然后,延迟计算还需要通过“精妙的”设计和约定来实现。

惰性求值的简单应用

let squareAndSum = (iterator, n) => {
  let result = 0
  while(n > 0) {
    try {
      result += Math.pow(iterator.next(), 2)
      n--
    }
    catch(_) {
      // length of list was lesser than `n` hence
      // iterator.next threw to signal it's out of values
      break
    }
  }
  return result
}
let getIterator = (arr) => {
  let i = 0
  return {
    next: function() {
      if (i < arr.length) return arr[i++]
      else throw new Error('Iteration done')
    }
  }
}
let squareAndSumFirst4 = (arr) => {
  let iterator = getIterator(arr)
  return squareAndSum(iterator, 4)
}

记忆化调用

// 普通递归
var count =0;//记录遍历次数
var fibonacci = function(n){
	count++;
	return n<2 ? n:fibonacci(n-1)+fibonacci(n-2);
}
//遍历11次后fibonacci()被调用了453次 ,我们调用了11次
function menoizationMethod(){
	var htmlStr = "";
	for ( var i = 0; i <=10; i++) {
		var tmp_count = count;
		htmlStr +="参数值:"+i+"\t和:"+fibonacci(i)+"\t该参数值下遍历次数:"+ (count-tmp_count)+"\t累计遍历次数:"+count+"\n";
	}
	console.log(htmlStr)
	count = 0;
}
menoizationMethod()
// 记忆递归
var count =0;//记录遍历次数
var fibonacci =function(){
	var memo = [0,1];
	var fib = function(n){
		var result = memo[n];
		count++;
		if(typeof result !== 'number'){
			result = fib(n-1) + fib(n-2);
			memo[n] = result;
		}
		return result;
	}
	return fib;
}();
//遍历11次后fibonacci()被调用了29次 ,我们调用了11次
function menoizationMethod(){
	var htmlStr = "";
	for ( var i = 0; i <=10; i++) {
		var tmp_count = count;
		htmlStr +="参数值:"+i+"\t和:"+fibonacci(i)+"\t该参数值下遍历次数:"+ (count-tmp_count)+"\t累计遍历次数:"+count+"\n";
	}
	console.log(htmlStr)
	count = 0;
}
menoizationMethod()

参考地址

https://www.jianshu.com/p/2975c25e4d71
https://blog.csdn.net/sergeycao/article/details/77448507
https://www.jianshu.com/p/66c71fb5ea62

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值