为了账号安全,请及时绑定邮箱和手机立即绑定

如何理解这个高阶函数闭包发生了什么

如何理解这个高阶函数闭包发生了什么

冉冉说 2021-10-07 10:31:52
我知道我下面的代码是错误的,但显然我遗漏了一些信息。我必须编写更复杂的高阶函数,但如果我不能真正理解简单的函数,我就没有机会。hof.add 应该返回传递的两个参数的总和。很简单...但鉴于我要创建这个高阶函数必须使用闭包。    hof.add = function(add) {      function makeAdd(a, b) {        return add(a + b);      }      return makeAdd;    };it('returns total of the two arguments', () => {        expect(hof.add(56, 5)).to.be.equal(56 + 5);        expect(hof.add(91, -71)).to.be.equal(91 + -71);      });(给出的框架建立在其之上)hof.add = function() { };
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

如果您只想使用一个参数名称,也许您打算对其进行解构:function(...add)


const not_hof = {};


// Cheating by using destructuring (...add) 

// and not a HOF since accepts only Numbers as arguments 

not_hof.add = function(...add) {  

  const makeAdd = add.reduce((prev, curr) => {

    return prev + curr;

  }, 0);

  return makeAdd; // and still not a HOF since it returns a Number 

};


console.log(not_hof.add(2, 3));              // 5

console.log(not_hof.add(9, 1, 10));          // 20

console.log(not_hof.add(1, 1, 1, 1, 1, 1));  // 6

PS:上面的函数也可以表示为:

not_hof.add = (...add) => add.reduce((prev, curr) =>  prev + curr, 0);

不是 HOF(高阶函数)

虽然很多人会说上面是一个高阶函数- 因为它返回Array.prototype.reduce,它实际上不是

维基百科 - 高阶函数

在数学和计算机科学中,高阶函数是至少执行以下一项操作的函数:

  • 将一个或多个函数作为参数(即过程参数),

  • 返回一个函数作为其结果。

但是,add不是一个程序函数的参数; IE:

过程 P(f):
返回 f(2,3) * f(9,1)

并且它不返回函数;而一个号码 返回Array.prototype.reduce

1. HOF - 一个或多个函数作为参数

至少传递一个函数作为参数

const helper = { // Helper functions

  add(a, b) { return  Number(a) + Number(b); },

};



const hof = {};

hof.add = function(fn, add1, add2) { // HOF since it takes a function as argument

  return fn(add1, add2);             // (Returns a Number)

};


// ...But it takes three arguments

console.log(hof.add(helper.add, 56, 5)); // 61

2. HOF - 返回一个函数

至少返回一个函数:


const hof = {};


hof.add = function(add) { // (Takes a Number argument)

  function makeAdd(b) {

    return add + b;

  }

  return makeAdd;         // HOF since it returns a function

};


// But accepts a single argument at each call

console.log(hof.add(56)(5)); // 61

或喜欢


const hof = {};

hof.add = function(add1, add2) { // NOT LIKE YOUR EXAMPLE, 2 arguments are expected!

  function makeAdd() {

    return add1 + add2;

  }

  return makeAdd; // HOF since it returns a function

};


// ...The function had to be executed ()

console.log(hof.add(56, 5)());     // 61

但在这种情况下,它无法通过您的测试说明:


it('returns total of the two arguments', () => { // nope :( only one argument here...


带闭合的 HOF

允许使用 a 多次调用该函数Function.prototype.toString(),以便在最后一次调用时返回字符串


const hof = {};


hof.add = function(add) {

  let sum = add;    // Store in local scope

  const makeAdd = (b) => {

    sum += b;       // Access to lexical environment variables

    return makeAdd; // Returns a function (self)  

  }

  makeAdd.toString = () => sum;

  return makeAdd;   // HOF since we return a function

}


const result = hof.add(1)(2)(2)(56);

console.log(result)         // (f) 61

console.log(typeof result); // function

console.log(result == 61)   // true

console.log(result === 61)  // false

// A legitimate test might break since the strict equality operator fails.

让我们保持简单。没有关闭,没有 HOF

如果不需要使用数组解构和 Array.prototype.reduce() 的第一个示例,那么只需坚持最简单的函数声明形式:


const not_hof = {

  add: (a, b) => a + b,

  sub: (a, b) => a - b,

  // etc...

};


console.log(  not_hof.add(56, 5)  ); // 61


查看完整回答
反对 回复 2021-10-07
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

为什么要在返回的函数中创建一个函数,而不是最初创建正确的函数?我会做这样的事情:


hof.add = function(a, b) {

    return (a + b);

};


查看完整回答
反对 回复 2021-10-07
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

高阶函数 (HOF) 只是接受函数作为参数或返回另一个函数的函数的一个奇特名称。如果我更了解您,您正在尝试创建一个可用于添加数字的加法器函数。使用您的示例 hof.add 是一个接收函数的 HOF,并返回另一个可用于将两个数字相加的函数


 hof.add = function(add) {

  function addFunc(a, b) {

    return add(a, b);

  }

  return addFunc;

}


function add(a, b){

  return a + b

}


const addNumbers = hof.add(add);

addNumbers(3, 14)

//17 as answer

addNumbers can recieve any two numbers and it will add them together.

add 是一个将两个数字相加的函数,它作为 hof.add 中的参数接收。hof.add 函数返回一个名为 addFunc 的函数,该函数又接收两个要相加的参数。干杯


查看完整回答
反对 回复 2021-10-07
  • 3 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信