简单的概念:
**1.函数柯里化:**一个函数原本有多个参数,只传入一个参数,生成一个新函数,由新函数接收剩下的参数来运行得到结构。
**2.偏函数:**一个函数原本有多个参数,只传入一部分参数,生成一个新函数,由新函数接收剩下的参数来运行得到结构。
**3.高阶函数:**一个函数参数是一个函数,该函数对参数这个函数进行加工,得到一个函数,这个加工用的函数就是高阶函数
函数柯里化在Vue中的应用:
场景: 如何判断一个标签是自定义标签还是HTML标签? Vue源码分析:
var isNonPhrasingTag = makeMap(
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
'title,tr,track'
);
其实Vue把HTML标签使用一个数据的形式保存起来,然后通过标签去数组中查找,如果存在就是HTML标签,不存在就是自定义标签!
makeMap函数就使用了函数柯里化:贴上源码:
/**
* Make a map and return a function for checking if a key
* is in that map.
*/
function makeMap(
str,
expectsLowerCase
) {
var map = Object.create(null);
var list = str.split(',');
for (var i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase
? function (val) {
return map[val.toLowerCase()];
}
: function (val) {
return map[val];
}
}
使用一个简化的例子,来解析makeMap方法以及如何使用:
/**
* 优化: 使用函数柯里化
*/
let tags = 'div, p, a, img, ul, li'.split(',');
function makeMap(keys) {
let set = {};
tags.forEach(key => set[key] = true); // tags = [div: true, p: true, a: true...]
return function (tagName) {
// !!逻辑非的取反运算, 双重否定等于肯定
return !!set[tagName.toLowerCase()] // true or false
}
}
let isHtmlTag = makeMap(tags) // 返回的函数
console.log(isHtmlTag('div'))
将代码运行在控制台上,可以看到结果:
1、如果是HTML标签:
2、如果是自定义标签:
普通的方式判断标签是否为HTML标签:
let tags = 'div, p, a, img, ul, li'.split(',');
function isHTMLTag(tagName) {
tagName = tagName.toLowerCase();
if (tags.indexOf(tagName) > -1) {
return true;
}
return false;
}
假如页面中2个标签,tags中有10 个标签,就需要比较20次; 而使用函数柯力化后,就不需要循环来判断,只需要2次判断即可,极大地提升了性能!