函数组合javascript
我试图理解Javascript中的函数组合,并遵循 我尝试了下面的程序,该程序将接受一个句子,将其分成若干部分(由空格分隔),并在每个单词上使用大写字母,然后返回一个单词数组函数组合javascript,javascript,functional-programming,Javascript,Functional Programming,我试图理解Javascript中的函数组合,并遵循 我尝试了下面的程序,该程序将接受一个句子,将其分成若干部分(由空格分隔),并在每个单词上使用大写字母,然后返回一个单词数组 function compose(f, g) { "use strict"; return function() { return f.call(this, g.apply(this,arguments)); } } var split = function (string, de
function compose(f, g) {
"use strict";
return function() {
return f.call(this, g.apply(this,arguments));
}
}
var split = function (string, delim) {
"use strict";
return string.split(delim);
};
var uppercase = function (string) {
"use strict";
if (string instanceof Array) {
return string.map(function (x) {
return x.toString().toUpperCase();
});
} else {
return string.toString().toUpperCase();
}
//return string.toString().toUpperCase();
};
var myfunc = compose(uppercase,split);
var data = myfunc("Elementary! My dear Watson",/\s+/);
console.log(data);
虽然我得到了我想要的,但代码在以下方面很难看:
如何即兴编写代码以获得“功能管道”,即。拆分->映射->大写?下面是一个小示例,介绍如何启动并运行一个流畅的界面,涵盖问题的第三部分。关键的一点是使用
newobj
创建一个对象,在方法中,您需要返回该对象以允许方法链接
Functional Javascript不允许使用链接方法,因为它没有内部状态,您可以使用Functional js来修饰和混合可以返回值或其他函数的其他函数
//MyObj在模块内声明,以使内部私有
var myObj=(函数(){
//构造函数
函数MyObj(字符串,delim){
this.input=字符串;
this.delim=delim;
}
//在其原型上创建MyObj方法
//所有方法都使用fluent函数进行了修饰
MyObj.prototype={
//拆分输入
拆分:流畅(函数(delim){
如果(!Array.isArray(this.input)){
this.input=this.input.split(delim!=null?delim:this.delim);
}
}),
//将文本转换为大写
大写:fluent(function(){
if(Array.isArray(this.input)){
this.input=this.input.map(函数(字符串){
返回字符串.toUpperCase();
});
}否则{
this.input=this.input.toUpperCase();
}
}),
//反转阵列
反向:fluent(函数(){
if(Array.isArray(this.input)){
this.input=this.input.reverse();
}
否则{
this.input=this.input.split(“”).reverse().join(“”);
}
}),
//如果你使用的是流畅的界面,或者决定你的终点是什么,你需要一个getter
get:function(){
返回此.input;
}
}
返回函数构造函数(字符串,delim){
返回新的MyObj(字符串,delim);
}
})();
//myObj是创建myObj的函数
console.log(myObj);
log(myObj(“基本的!我亲爱的Watson)”,/\s+/).split().uppercase().get());
//使用该代码,您可以覆盖默认的delimeter
console.log(myObj(“初等!我亲爱的Watson)”,/\s+/).split(“”).uppercase().get());
//运行不同的方法
log(myObj(“基本的!我亲爱的Watson)”,/\s+/).split().uppercase().reverse().get());
//秩序不再重要
log(myObj(“基本的!我亲爱的Watson)”,/\s+/).reverse().uppercase().split().get());
//MyObj还有一个内部状态,因此您可以
//函数装饰器-这将使原型方法返回一个值或
函数fluent(方法){
返回函数(){
var ret=method.apply(这是参数);
return ret!=null
?ret
:这个;
}
}
这里的代码与您使用的代码类型相同,并且经过了一些简化。如果这是你想要的编码方向,我不能推荐Reg Braith的Javascript Allonge等等,它完全改变了我编写代码的想法
希望这个小例子展示了如何组合函数,以及函数js是多么有用。另一个很大的好处是,如果您使用的纯函数不考虑外部范围,那么您可以轻松地调试问题,因为您可以遵循可靠的函数调用流
我花了大约6个月的时间和不断的实践,学习了足够多的功能,以便能够理解它的基本概念。但这是非常值得的努力
“严格使用”//您只需要对HHOLE文件进行一次严格的使用
//对于compose,您不应该真正需要调用或应用,因为这始终是纯函数的窗口
函数组合(a,b){
返回函数(c){
返回a(b(c));
}
}
//split现在是一个简单的函数,它接受delimeter并返回一个拆分字符串的函数
功能拆分(delim){
返回函数(字符串){
返回字符串.split(delim);
}
};
//如果您添加一个函数映射器,您可以消除一些大写的复杂性
//并用大写字母组成地图
功能图(fn){
返回函数(arr){
返回Array.prototype.map.call(arr,fn);
}
}
//这是一个非常简单的单一责任函数,可以由
函数大写(字符串){
返回字符串.toUpperCase();
};
变量
splitBySpace=split(/\s+/),
arrToUpper=map(大写),
myfunc=组合(arrToUpper,splitBySpace);
log(arrToUpper(['one','two']);
log(myfunc(“初等!我亲爱的沃森”);
//如果要在不同的字符上拆分,则需要通过使用不同的delimeter创建新的拆分函数
变量
splitByChar=split(“”),
splitByBang=split(“!”);
//您也不必编写函数,您可以正常地编写它们,但要遵循这些函数要困难得多。
log(map(大写)(拆分(“”)(“初等!我亲爱的沃森”)代码>
函数组合就是将两个或多个函数组合成一个函数。我已经写了一个很容易理解的东西,我想它会为你澄清很多事情
然而,您想要的是非常不同的东西,并且在javascript中非常直接
"Elementary! My dear Watson".split(/\s+/).map(val => val.toUpperCase());
<
function myFunct(str, delim) {
str.split(delim).map(val => val.toUpperCase());
}
const SALES_TAX = 0.08;
const COUPON_CODES = {
AAAA: 0.1,
BBBB: 0.07,
CCCC: 0.15,
};
const shoppingtotal = shoppingCart =>
shoppingCart.reduce((acc, item) => {
acc += item.price * item.qty;
return acc;
}, 0);
const discount = couponCode => amount =>
amount * (1 - COUPON_CODES[couponCode]);
const tax = amt => amt * (1 + SALES_TAX);
const compose = fns => input => fns.reduce((acc, fn) => fn(acc), input);
const calculatePayment = compose([shoppingtotal, discount('AAAA'), tax]);
calculatePayment([
{
name: 'pencil',
price: 1,
qty: 2,
},
{
name: 'Pen',
price: 1.5,
qty: 20,
},
{
name: 'Eraser',
price: 0.25,
qty: 10,
}])