[JS]13.闭包应用(柯里化函数 & 实现reduce)

430 阅读2分钟

1. 柯里化

  • 预处理思想(预先存储,后续拿来直接用)
  • 执行函数,形成一个闭包,把一些信息(私有变量和值)存储起来,闭包的保存作用
  • 以后其下级上下文中,如果需要用到这些值,直接基于作用域链查找机制,找到后拿来用

1. 实现函数

let res = fn(1, 2)(3);
console.log(res); // 6 => 1+2+3
  • 实现1
function fn() {
  // 存储执行fn传递的实参,类数组,转化为数组,才有concat方法
  let outerArgs = Array.from(arguments);
  return function anonymous() {
    // 存储执行第二个函数传递的实参
    let innerArgs = Array.from(arguments);
    // 参数拼接
    let params = outerArgs.concat(innerArgs);
    // reduce求和
    return params.reduce(function(result, item, index){
      return result + item;
    })
  };
}
  • 实现2
// es6 剩余运算符, 本来就是数组
const fn = (...outerArgs) => {
  return (...innerArgs) => {
    return outerArgs.concat(innerArgs).reduce((result, item) => {
      return result + item;
    })
  }
}
// 一行简写 return 一行
const fn = (...outerArgs) => (...innerArgs) => outerArgs.concat(innerArgs).reduce((result, item) => result + item

2.数组求和办法

2.1 eval执行字符串
[10, 20, 30].join('+')   // => "10+20+30"
eval("10+20+30")   // => 60
2.2 循环遍历
let arr = [10, 20, 30],
    total = 0;
arr.forEach(function(item) {
  total += item;
})
2.3 reduce:
  • 依次遍历数组的每一项,把上一轮遍历的结果作为下一轮遍历的起始参数
  • arr.reducr([function], [calue])
let arr = [10, 20, 30, 40];
let result = arr.reduce(function(result, item, index) {
  // 第一轮遍历,10(数组的第一项作为result的初始值),20, 1
  // 第二轮遍历,30(上一轮遍历函数返回的结果,是下一轮result的值),30, 2
  // 第三轮遍历,60(上一轮遍历函数返回的结果,是下一轮result的值),40, 3
  console.log(result, item, index)
  return result + item;
})

/*
  有初始值 0
*/
let result = arr.reduce(function(result, item, index) {
  // 第一轮遍历,0(最后一个参数),10, 1
  // 第二轮遍历,10(上一轮遍历函数返回的结果,是下一轮result的值),20, 2
  // 第三轮遍历,30(上一轮遍历函数返回的结果,是下一轮result的值),30, 3
  // ...
  console.log(result, item, index)
  return result + item;
}, 0)

2.实现reduce

function reduce(arr, callback, initValue) {
  let result = initValue,
      i = 0;
  // 没有传递 initValue 初始值,把数组第一项作为result初始值,遍历从第二项开始    
  if(typeof result === "undefined") {
    result = arr[0];
    i = 1;
  }
  
  // 遍历数组中每一项,每一次遍历都会执行callback
  for(; i < arr.length; i++) {
    result = callback(result, arr[i], i);
  }
  
  return result;
  
}
let arr = [10, 20, 30, 40];
let result = reduce(arr, function(result, item, index) {
  return result + item;
})
console.log(result); // 100