2017-08-31 7 views
-4

私はES6の新機能です。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"); 
 
    }); 
 
});

+4

単に文脈から問題を述べ、コミュニティがそれを解決することを期待している投稿をお勧めします。あなた自身でそれを解決しようとしたと仮定した場合、あなたがあなたの考えを書いて、あなたが理解できなかったものが役立つかもしれません。間違いなくあなたの投稿への回答が増えます。それまでは、質問は閉会投票/投票投票に投票されます。 – Cerbrus

答えて

2

これは可能ですが、少し奇妙な、私は現実の生活の中でこのような何かを行うことはありません。

一般に、関数を返す関数は「2次関数」と呼ばれます。関数を返す関数を返す関数は、「3次」関数です。あなたがしようとしているのは、引数に応じて異なる順序を持つ関数を書くことです。これは、読み込みとメンテナンスが本当に混乱します。

JavaScriptを使用すると、戻り値の型がわかりにくくなるので、それを行うことができます。ここで私が使用したいコードです

+1

私はこれを考慮しましたが、その方法で第2のパラメータを使用するのではなく、クロージャを代わりに使用しました。しかし、仕事をしないでください。 – RobG

1

もちろん、bは引数が渡​​されていない場合、関数を返すことがあり

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"));
(ES6のデフォルト変数と再帰を使用しています)。この関数は同じように動作します。引数が渡されない場合は、自身を返します。さらに、関数の呼び出し回数を把握しておく必要があります。

以下の溶液が、それ以外の場合は"b"から成る文字列を作成し、その引数がfalsyある場合、カウントをインクリメントする内部関数を作成し、"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'));

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. 文字が提供された後に呼び出しを行うと、文字列を呼び出そうとしますが、エラーが発生します。繰り返しますが、ユーザーが試してみると、手紙が提供されたら電話を停止する方法はありません。
+0

はい、私は同意します。これが私がこのアプローチを強く妨げている理由の1つです!しかし、それはテストに合格します。 –

+0

@DuncanThackerあなたのソリューションは同じ問題を抱えています:Pこれ以上のものもあります。なぜあなたは**このアプローチを強く避けているのだろうか?このアプローチはあなたのアプローチよりも優れているからです。 – Rifat

+0

申し訳ありませんが、私は実生活でやろうとしないことを達成しようとしています。あなたの解決策(と私の)が質問に正しく答える、私はあなたの答えを落とそうとしていなかった、 –