【问题标题】:A function that can both compose and chain (dot notation) in Javascript一个在 Javascript 中既可以组合又可以链接(点符号)的函数
【发布时间】:2016-12-31 08:23:18
【问题描述】:

我正在尝试转换一个使用大量点符号链接的旧 api,需要保留即:

[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 的小例子。

【问题讨论】:

    标签: javascript functional-programming lodash ramda.js


    【解决方案1】:

    编辑

    我想我最初误解了你。你想要一个函数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,并且前缀功能将正常工作。这也允许您在每个对象类型(数组、字符串、其他...)上拥有一个独特的 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]

    【讨论】:

    • 感谢您的指点,这就是为什么我倾向于使用 ramda,因为所有函数都是 curried :)
    • @cmdv 我似乎误解了你的初衷。我用新的理解重新编写了我的答案。
    • 谢谢你,非常彻底,我可以带走很多东西
    • 用你的回答我将不得不向 Array + String 添加新的原型 什么是保持这个内联在它自己的函数中的方法?我有 100 个奇怪的函数需要像这样转换并担心名称冲突。
    • @cmdv 现在不是都在原型上定义了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    相关资源
    最近更新 更多