我是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");
});
});
这是可能的,但有点奇怪,我永远不会在现实生活中做这样的事情。
通常,返回函数的函数称为"二阶"函数。返回返回函数的函数的函数是"三阶"函数。您要做的是编写一个函数,该函数的顺序取决于参数,这确实令人困惑地阅读和维护。
话虽如此,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") );
您可以使用闭合并命名函数表达式,请参见注释。我不喜欢重复的行,但无法使用这种模式避免。
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'));
这种模式的问题是:
- 如果上次通话中未提供任何字母,它将返回函数。特定的电话无法知道这是最后一个。
- 如果在提供了字母后拨打电话,它将尝试调用一个字符串,这将丢弃错误。同样,如果用户尝试使用字母,就无法停止呼叫。
显然,如果没有参数传递给它,则b
必须返回函数。此函数的作用相同:如果没有参数传递给它,则它会返回自身。此外,我们必须跟踪调用功能的次数。
以下解决方案创建一个内部函数,该函数会增加计数,如果其参数是虚假的,则创建一个由"b"
组成的字符串,"o"
重复了数量和参数的值多次:
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'));