2017-08-31 81 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

這是可能的,但有點怪異,我永遠不會做這樣的事情在現實生活中。

通常,返回函數的函數稱爲「二階」函數。返回函數的函數是一個「三階」函數。你要做的是寫一個函數,它具有不同的順序,這取決於參數,這對讀取和維護來說是非常混亂的。

話雖如此,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

我考慮過這個,但不喜歡使用第二個參數,而是使用閉包。儘管這樣做。 – RobG

1

顯然,b有如果沒有參數傳遞給它返回的功能。這個函數的作用方式相同:如果沒有參數傳遞給它,它將返回自身。而且,我們必須跟蹤我們的函數被調用了多少次。

以下解決方案創建如果它的參數是falsy其遞增計數的內部功能,否則創建包含"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'));

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

是的,我同意,這是我強烈反對這種做法的原因之一!它確實通過了測試。 –

+0

@DuncanThacker你的解決方案有同樣的問題:P甚至比這個更多。我想知道爲什麼你**強烈不鼓勵**這種方法?因爲這種方法比你的方法更好。 – Rifat

+0

抱歉不清楚 - 問題是試圖完成一些我在現實生活中永遠不會去做的事情。你的解決方案(和我的)正確回答了這個問題,我並沒有試圖解決你的問題, –