ES6函数帮助 - 返回函数的函数

时间:2017-08-31 11:54:50

标签: javascript ecmascript-6

我是ES6的新手。

尝试通过一些测试来学习。

请帮我解决一下通过测试的实施方法。

// dependencies:
const expect = require('chai').expect;

 // implement this:
 function b(x){
   // return "b"+ x;
   //  return (x) =>  "bo" + x;
    
 }
// unit tests:
describe("implement function b", function() {
  it("SHOULD work for the following cases", function() {
    console.log(b()("m"));
    expect(b("m")).to.equal("bm");
    expect(b()("m")).to.equal("bom");
    expect(b()()("m")).to.equal("boom");
    expect(b()()()("m")).to.equal("booom");
    expect(b()()()()("t")).to.equal("boooot");
  });
});

3 个答案:

答案 0 :(得分:2)

这是可能的,但有点奇怪,我永远不会在现实生活中做这样的事情。

通常,返回函数的函数称为“二阶”函数。返回返回函数的函数的函数是“三阶”函数。你要做的是根据参数编写一个具有不同顺序的函数,这实际上让人难以阅读和维护。

话虽如此,javascript对于返回类型并不挑剔,所以你可以这样做。这是我使用的代码(使用ES6默认变量和递归)

function b(lastLetter, prefix = "b") {
  if (lastLetter) {
    //if we're ending the chain, return everything so far with the last letter on the end
    return prefix + lastLetter;
  }
  //if not, then return version of this function with a slightly longer prefix
  return lastLetter => b(lastLetter, prefix + "o");
}

console.log( b("m") );
console.log( b()("m") );
console.log( b()()("m") );
console.log( b()()()()()()()("t") );

答案 1 :(得分:2)

您可以使用闭包和命名函数表达式,请参阅注释。我不喜欢重复的行,但不能用这种模式来避免它。

function b(x) {

  // On the first call, setup prefix 
  var prefix = 'b';

  // End early if x provided on first call
  if (x) return prefix + x;

  // Otherwise, return a function that can be chained
  return function foo(x){
    prefix += 'o';
    if (x) return prefix + x;
    return foo;
  } 
}

console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));
console.log(b()()()()('t'));

这种模式的问题是:

  1. 如果最后一次通话中没有提供任何字母,则返回一个功能。特定的电话无法知道它是最后一次。
  2. 如果在提供信件后进行了呼叫,它将尝试调用字符串,这将引发错误。同样,如果用户尝试提供信件,则无法停止呼叫。

答案 2 :(得分:1)

显然,如果没有传递参数,b必须返回一个函数。此函数的行为方式相同:如果没有传递参数,则返回自身。此外,我们必须跟踪我们调用函数的次数。

以下解决方案创建一个内部函数,如果其参数为假,则递增计数,否则它会创建一个由"b"组成的字符串,"o"重复次数与count指定的次数和值论证:



const b = v => {
  let n = 0; // this is our counter
  const f = e => {
    if (e !== undefined) {
      // an argument was passed, return the correct value
      return 'b' + 'o'.repeat(n) + e;
    }
    // no argument was passed, increment the counter and return the function
    n += 1;
    return f;
  };
  // call the function the first time with the initial value
  return f(v);
};

console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));
console.log(b()()()('t'));