javaScript---惰性函数、函数记忆和函数组合

189 阅读2分钟

惰性函数

需要写一个函数返回首次调用的时间,可以用闭包试下:

var foo = (function() {
    var t;
    return function() {
        if (t) return t;
        t = new Date();
        return t;
    }
})();
console.log(foo())
console.log(foo())
console.log(foo())
//2021-12-13T10:22:52.363Z
//2021-12-13T10:22:52.363Z
//2021-12-13T10:22:52.363Z

这种也是需要先判断是否有t,可以使用惰性函数来解决每次都需要判断的问题:

var foo = function() {
    var t = new Date();
    foo = function() {
        return t;
    };
    return foo();
};
console.log(foo())
console.log(foo())
console.log(foo())
// 2021-12-13T10:25:34.392Z
// 2021-12-13T10:25:34.392Z
// 2021-12-13T10:25:34.392Z

这种惰性函数就是重写foo函数,将第一次生成的t返回出去,这就形成了一个闭包,后续每次调用foo实际上执行的就是foo内部的匿名函数,将闭包返回出去。

函数记忆

函数记忆是指将上次的计算结果缓存起来,当下次调用时,如果遇到相同的参数,就直接返回缓存中的数据。

《JavaScript权威指南》中写过一个memoize:

function memoize(f) {
    var cache = {};
    return function(){
        var key = arguments.length + Array.prototype.join.call(arguments, ",");
        if (key in cache) {
            return cache[key]
        }
        else {
            return cache[key] = f.apply(this, arguments)
        }
    }
}

这种就是用一个闭包来存储函数执行的值,key是参数长度和参数组成的字符串,执行函数前先遍历存储对象,如果存在key就返回对象中的值,如果不存在就执行函数并存储在对象中。

因为使用join拼接字符串,然而如果是个参数是对象就会出问题,可以更改下:

var memoize = function(func, hasher) {
    var memoize = function(key) {
        var cache = memoize.cache;
        var address = '' + (hasher ? hasher.apply(this, arguments) : key);
        if (!cache[address]) {
            cache[address] = func.apply(this, arguments);
        }
        return cache[address];
    };
    memoize.cache = {};
    return memoize;
};

函数组合

我们需要写一个函数,输入 'kevin',返回 'HELLO, KEVIN'。

var toUpperCase = function(x) { return x.toUpperCase(); };
var hello = function(x) { return 'HELLO, ' + x; };

var greet = function(x){
    return hello(toUpperCase(x));
};

greet('kevin');

然而这种由内向外的写法,一旦嵌套层数过多,可读性就会很差,希望改写成从左向右的写法:

function compose() {
    var args = arguments;
    var start = args.length - 1;
    return function() {
        var i = start;
        var result = args[start].apply(this, arguments);
        while (i--) result = args[i].call(this, result);
        return result;
    };
};
var toUpperCase = function(x) { return x.toUpperCase(); };
var hello = function(x) { return 'HELLO, ' + x; };

let a = compose(hello,toUpperCase)
console.log(a('nick'))

这种就是取得compose参数的最后一个函数,并将执行的结果依次传递给前一位,执行完毕后返回。