骚操作-函数柯里化
科里化函数:固定某个函数的一些参数,得到该函数剩余参数的一个新函数,如果没有剩余参数,则调用
js
/**
* 科里化函数
* 在函数式编程中,科里化最重要的作用是把多参函数变为单参函数
*/
this.myPlugin.curry = function (func) {
//得到从下标1开始的参数
var args = Array.prototype.slice.call(arguments, 1);
var that = this;
return function () {
var curArgs = Array.from(arguments); //当前调用的参数
var totalArgs = args.concat(curArgs);
if (totalArgs.length >= func.length) {
//参数数量够了
return func.apply(null, totalArgs);
} else {
//参数数量仍然不够
totalArgs.unshift(func);
return that.curry.apply(that, totalArgs);
}
};
};柯里化的应用场景
柯里化的应用就是为了固定函数的参数,属于函数式编程的思想,比较难理解。
js
function f(x, y, z) {
return (x + y) * z;
}
// 求:(2+3)*5 (2+5)*6 (2+4)*7 (2+4)*16
var g = myPlugin.curry(f, 2); //固定第一个参数
console.log(g(3, 5));
console.log(g(5, 6));
var y = g(4); // 相当于var y = myPlugin.curry(f, 2, 4);
console.log(y(7));
console.log(y(16));html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.container {
border: 2px solid;
padding: 30px;
}
</style>
</head>
<body>
<div class="container"></div>
<script src="../../plugin/helpers.js"></script>
<script>
//创建一个元素,传入对应的参数
function createElement(container, name, props, styles, content) {
var ele = document.createElement(name);
container.appendChild(ele);
for (var prop in props) {
ele[prop] = props[prop];
}
for (var prop in styles) {
ele.style[prop] = styles[prop];
}
if (content) {
ele.innerHTML = content;
}
}
//固定响应的参数,然后简化调用
var div = document.querySelector(".container");
var create = myPlugin.curry(
createElement,div,"div",{},
{
height: "100px",
background: "#008c8c",
margin: "30px",
color: "#fff",
}
);
create("asdfasdf");//所有的调用都被简化了
create("2344");
create("asdfa4545sdf");
create("asdfa234324234sdf");
create("asdfa132112313sdf");
create("563456435634");
create("啊打发法是发啊手动阀啊");
</script>
</body>
</html>:::
骚操作-函数管道
函数管道:将多个单参函数组合起来,形成一个新的函数,这些函数中,前一个函数的输出,是后一个函数的输入
js
/**
* 函数管道
*/
this.myPlugin.pipe = function () {
var args = Array.from(arguments);
return function (val) {
return args.reduce(function (result, func) {
return func(result);
}, val);
// 第二种写法
// for (var i = 0; i < args.length; i++) {
// var func = args[i];
// val = func(val);
// }
// return val;
}
}应用场景:
js
//将字符串中每一个单词首字母大写
function everyFirstLetterUp(str) {
return str.replace(/\b(\w)(\w*)\b/g, function($, $1, $2) {
return $1.toUpperCase() + $2;
});
}
//将字符串中除首字母外的其他字母小写
function otherLetterLower(str) {
return str.replace(/\b(\w)(\w*)\b/g, function($, $1, $2) {
return $1 + $2.toLowerCase();
});
}
//去掉字符串中所有的空白字符
function removeEmpty(str) {
return str.replace(/\s+/g, "");
}
//将字符串中第一个单词字符小写
function firstLetterLower(str) {
return str.replace(/\w/, function($) {
return $.toLowerCase();
});
}
//截取字符串
function curString(number, str) {
return str.substr(0, number);
}
//以上准备了很多工具函数,接下来要将字符串转变为小驼峰命名法
let str=" MY fIrST naME";
// 普通写法 需要调用很多次
str=everyFirstLetterUp(str);
str=otherLetterLower(str);
str=removeEmpty(str);
str=firstLetterLower(str);
str=curString(10, str);
// 使用函数管道将流程封装即可,当遇到不是单参函数,可以使用柯里化变成单参函数
var smallCamel = myPlugin.pipe(
everyFirstLetterUp,
firstLetterLower,
otherLetterLower,
removeEmpty,
myPlugin.curry(curString, 10)
);
console.log(smallCamel(" MY fIrST naME"));
console.log(smallCamel(" asdfasf sdfasf ggggggg hGDGF"));