有关函数柯里化的理解

951 阅读2分钟

简单的概念:

**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标签:

image.png

2、如果是自定义标签:

image.png

普通的方式判断标签是否为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次判断即可,极大地提升了性能