柯里化函数的实现

记录柯里化函数实现的学习过程:

柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果。

如果要实现下面这个方法:

add(2)(1, 3, 4)(2, 3)(3)(4, 6)(7, 98)() // 133

上面这个函数当参数为空的时候执行了内部参数所有值的相加,所以我们应该考虑当参数不为空的时候将缓存起来,在为空的时候再相加,这样的思路会用闭包的方式来实现。下面是实现方法:

function add () {
  // 用来缓存所有的arguments值  
  let args = [].slice.call(arguments);
  // 新建currying函数实现柯里化  
  let currying = function () {
    // 如果参数为空,那么递归停止,返回执行结果
    if (arguments.length === 0) {
      return args.reduce((a, b) => a + b);
    } else {
      // 否则将参数保存到args里面,返回currying方法
      args.push(...arguments);
      return currying
    }      
  }
  return currying
}
add(2)(1, 3, 4)(2, 3)(3)(4, 6)(7, 98)() // 133

上面有需要注意的一点,因为currying函数里面使用arguments,所以currying不能使用箭头函数,箭头函数内部的arguments的用法与箭头函数内部的this差不多,它取的是上一级函数的arguments值。如果想用箭头函数,currying函数可以这样改动:

  let currying = (...rest) => {
    // 如果参数为空,那么递归停止,返回执行结果
    if (rest.length === 0) {
      return args.reduce((a, b) => a + b);
    } else {
      // 否则将参数保存到args里面,返回currying方法
      args.push(...rest);
      return currying
    }      
  }

我们返回的currying函数还可以使用callee来实现,原理相同,但是严格模式下不能使用:

function add () {
  // 用来缓存所有的arguments值  
  let args = [].slice.call(arguments);
  // 新建currying函数实现柯里化  
  return function () {
    // 如果参数为空,那么递归停止,返回执行结果
    if (arguments.length === 0) {
      return args.reduce((a, b) => a + b);
    } else {
      // 否则将参数保存到args里面,返回currying方法
      args.push(...arguments);
      return arguments.callee
    }      
  }
}
add(2)(1, 3, 4)(2, 3)(3)(4, 6)(7, 98)() // 133

对普通函数进行柯里化:

// 柯里化函数的构造方法
function curry (fn) {
  // 缓存除第一个参数的所有参数
  let args = [].slice.call(arguments, 1);  
  let _fn = function () {
    if (arguments.length === 0) {
      return fn.apply(this, args)
    } else {
      args.push(...arguments);
      return _fn
    }
  }
  return _fn
}
function add () {
  return [].reduce.call(arguments, (a, b) => a + b)
}
console.log(curry(add, 2)(1, 3, 4)(2, 3)(3)(4, 6)(7, 98)()) // 133

举例柯里化函数思想实现的场景:

如减少重复传递的参数

function simpleURL(protocol, domain, path) {
    return protocol + "://" + domain + "/" + path;
}

我们使用的时候将会这样:

var myurl = simpleURL('http', 'mysite', 'home.html');
var myurl2 = simpleURL('http', 'mysite', 'aboutme.html');

我们可以用柯里化的思想改写:

function curry (fn) {
  // 缓存除第一个参数的所有参数
  let args = [].slice.call(arguments, 1);  
  return function () {return fn.apply(this, args.concat(...arguments))
  }
}


// 避免每次调用重复传参
let myURL1 = curry(simpleURL, 'https', 'mysite');
let res1 = myURL1('home.html');    //

console.log(res1);//https://mysite/home.html

let myURL2 = curry(simpleURL, 'http', 'mysite');
let res2 = myURL2('aboutme.html');    //

console.log(res2);//http://mysite/aboutme.html

 

转载于:https://www.cnblogs.com/kdcg/p/10192421.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值