2016-08-24 9 views
5
撰寫和鏈(點表示)的函數

我試圖轉換使用了很多點符號鏈接的需要被保留,即舊的API:既能在Javascript

[1,2,3,4].newSlice(1,2).add(1) // [3] 

我倒要添加的成分的功能性風格在這個例子中Ramda但lodash或其他人將被罰款:

const sliceAddOne = R.compose(add(1), newSlice(1,2)) 
sliceAddOne([1,2,3,4])// [3] 

我的問題是如何能做到既鏈接和組成在我的功能newSlice將這個函數是什麼樣子?

我有一點點jsBin的例子。

回答

3

編輯

我想我最初誤解了你。你想要一個功能f,您可以調用作爲

f(...args)(someObj) === someObj.f(...args) 

我是這樣做的

// infix 
Array.prototype.newSlice = function(x,y) { return this.slice(x,y) } 

// prefix 
const newSlice = (x,y) => F => F.newSlice(x,y) 

這是一個很好的設計,因爲你可以實現你想要的任何對象newSlice上有newSlice能力和前綴功能將正常工作。這也允許你在每個對象類型(Array,String,Other ...)上擁有newSlice的唯一實現,因爲它很可能是我們正在分割的底層數據將會不同 - 你得到所有這些而不需要做愚蠢的條件this檢查您的功能的正文。

// newSlice :: [a] -> (Integer,Integer) -> [a] 
 
Array.prototype.newSlice = function(x,y) { 
 
    return this.slice(x,y) 
 
} 
 

 
// newSlice :: String -> (Integer,Integer) -> String 
 
String.prototype.newSlice = function(x,y) { 
 
    return this.substring(x,y) 
 
} 
 

 
// even on a custom object 
 
class LottoTicket { 
 
    constructor(...nums) { this.nums = nums } 
 
    newSlice(x,y) { return this.nums.slice(x,y) } 
 
} 
 

 
// newSlice :: (Array, String) a => (Integer,Integer) -> a -> a 
 
const newSlice = (x,y) => F => F.newSlice(x,y) 
 

 
// use it in prefix position 
 
console.log(newSlice(1,2)([1,2,3,4]))    // [2] 
 
console.log(newSlice(1,2)("abcd"))     // 'b' 
 
console.log(newSlice(1,2)(new LottoTicket(9,8,7))) // [8] 
 

 
// use it infix position 
 
console.log([1,2,3,4].newSlice(1,2))    // [2] 
 
console.log("abcd".newSlice(1,2))     // 'b' 
 
console.log((new LottoTicket(9,8,7)).newSlice(1,2)) // [8]

+0

感謝您的指針,這就是爲什麼我傾向於使用ramda所有功能都令行禁止:) – cmdv

+0

@cmdv我似乎誤認爲您最初的意圖。我用一種新的理解重新回答了我的答案。 – naomik

+0

謝謝你,非常徹底和充足的我拿走 – cmdv

相關問題