在Javascript中可以组合和链接(点表示法)的函数

A function that can both compose and chain (dot notation) in Javascript

本文关键字:表示 函数 链接 Javascript 组合      更新时间:2023-09-26

我正在尝试转换一个旧的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的例子

EDIT

我想我一开始误解你了。你想要一个函数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]