手记

JavaScript高阶函数与函数柯里化

基本概念

满足下列条件之一的函数就可以称为高阶函数。
1、函数作为参数被传递;
2、函数作为返回值输出。

函数作为参数被传递

把函数当作参数传递,这代表我们可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数参数中,这样一来可以分离业务代码中变化与不变的部分。其中一个重要应用场景就是常见的回调函数。

例子:

[1, 4, 2, 5, 0].sort((a, b) => a - b);
//输出:[0, 1, 2, 4, 5]
        
[0, 1, 2, 3, 4].map(v => v + 1);
//输出:[1, 2, 3, 4, 5]
        
[0, 1, 2, 3, 4].every(v => v < 5);
//输出:true

函数作为返回值输出

让函数继续返回一个可执行的函数,意味着运算过程是可延续的。

例子:

const fn = (() => {
    let myFamily = [];
    return {
        addPerson(name) {
            if (myFamily.includes(name)) {
                return false;
            }
            myFamily.push(name);
        },
        showPerson(name) {
            if (Object.is(myFamily.length, 0)) {
                return false;
            }
            return myFamily.join(",");
        }
    }
})();
fn.addPerson("爸爸");
fn.addPerson("妈妈");
fn.showPerson(); //输出:爸爸,妈妈

同时满足两个条件的高阶函数

例子:

const plus = (...args) => {
    let n = 0;
    for (let i = 0; i < args.length; i++) {
        n += args[i];
    }
    return n;
}

const mult = (...args) => {
    let n = 1;
    for (let i = 0; i < args.length; i++) {
        n *= args[i];
    }
    return n;
}

const createFn = (fn) => {
    let obj = {};
    return (...args) => {
        let keyName = args.join("");
        if (keyName in obj) {
            return obj[keyName];
        }
        obj[keyName] = fn.apply(null, args);
        return obj[keyName];
    }
}

let demo1 = createFn(plus);
console.log(demo1(2, 2, 2)); //输出:6

let demo2 = createFn(mult);
console.log(demo2(2, 2, 2)); //输出:8

函数柯里化

函数柯里化又称部分求值。一个柯里化的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

例子:

const cost = (() => {
    let arr = [];
    return (...args) => {
        if (args.length === 0) {
            let money = arr.reduce((p, c) => p + c);
            return money;
        } else {
            arr.push(parseInt(args));
        }
    }
})();
cost(100);
cost(100);
cost();
//输出:200

上例中,当调用cost()时,如果明确地带上了一些参数,表示此时并不进行真正的求值计算,而是把这些参数保存起来,此时让cost函数返回另外一个函数。只有当我们以不带参数的形式执行cost()时,才利用前面保存的所有参数,真正开始进行求值计算。函数柯里化赋予函数的是一种“预加载”的能力。

高价函数的意义

闭包和高阶函数在JavaScript的设计模式中应用极多,后续有关于设计模式的手记中会详细讲解。


如有错误,欢迎指正,本人不胜感激。

1人推荐
随时随地看视频
慕课网APP