好的,我有另一个答案,在我看来这个答案相当创新。
基本上,与Naomik的答案类似的做法的问题在于,您每次链接方法时都会创建函数。
编辑:此解决方案存在相同问题,但是为了教育目的而保留此答案。
因此,在这里,我提供一种仅将新值绑定到您的方法(基本上只是独立函数)的方法。这还提供了从不同模块导入函数到新构建的对象的额外好处。
好的,下面开始。
const assoc = (prop, value, obj) =>
Object.assign({},obj,{[prop]: value})
const reducer = ( $values, accumulate, [key,val] ) => assoc( key, val.bind( undefined,...$values ), accumulate )
const bindValuesToMethods = ( $methods, ...$values ) =>
Object.entries( $methods ).reduce( reducer.bind( undefined, ...$values), {} )
const prepareInstance = (instanceMethods, staticMethods = ({}) ) => Object.assign(
bindValuesToMethods.bind( undefined, instanceMethods ),
staticMethods
)
const RightInstanceMethods = ({
chain: (x,f) => f(x),
map: (x,f) => Right(f(x)),
fold: (x,l,r) => r(x),
inspect: (x) => `Right(${x})`
})
const RightStaticMethods = ({
of: x => Right(x)
})
const Right = prepareInstance(RightInstanceMethods,RightStaticMethods)
现在您可以做到:
Right(4)
.map(x=>x+1)
.map(x=>x*2)
.inspect()
您也可以这样做。
Right.of(4)
.map(x=>x+1)
.map(x=>x*2)
.inspect()
你还有一个额外的好处,即可以从这些模块中导出内容。
export const Right = prepareInstance(RightInstanceMethods,RightStaticMethods)
虽然你无法获得ClassInstance.constructor
,但你可以使用FunctorInstance.name
(注意,你可能需要使用polyfill来填充Function.name
并且不使用箭头函数导出以便与Function.name
的浏览器兼容性保持一致)
export function Right(...args){
return prepareInstance(RightInstanceMethods,RightStaticMethods)(...args)
}
PS - 欢迎为“prepareInstance”提供新的命名建议,有关详细信息,请参见Gist。
https://gist.github.com/babakness/56da19ba85e0eaa43ae5577bc0064456
return new Foo(arg);
。 - jfriend00new
关键字。不过,我打算将其用于其他用途。 - MulanFoo().bar()
代码与(new Foo()).bar()
进行比较即可。它很糟糕。创建新对象有什么重要性呢?创建对象是日常例行公事,我不需要特殊的语法来完成它。 - user619271