首页 > 解决方案 > 不理解高阶函数(使用 javascript 的问题示例)

问题描述

我目前正在学习 Javascript 基础知识,尤其是高阶函数。我阅读了许多文章并观看了许多视频,其中人们解释了基本定义并演示了高阶函数的最基本构造。但是,当我遇到实际问题时,我迷路了。这是一个例子(这只是为了我的个人学习,不是为了成绩或工作):

编写一个maybe函数,给定一个谓词(一个返回布尔值的函数)和任何其他函数,如果前者返回true,则只调用后者:maybe(x => x > 100, myFn)。如果谓词返回 true,则应将 x 的值传递给 myFn。如果谓词返回 false,x 应该原样返回。

我不明白如何将 x 的值从一个函数传递给另一个函数......

除了谓词函数和回调函数之外,我还通过添加一个 number 参数来解决这个问题。但是,提示中只指定了两个参数,所以我想我没有正确执行。这是我所做的:

//predicate (evaluates to a boolean)
const notZero = function(x) {
    //console.log('predicate runs!');
    return x !== 0;
}

//callback (does something within the main function)
const plusOne = function(x) {
    //console.log('callback runs!');
    return x + 1;
}

//checking if my predicate works
//test(notZero(1), true); // => test passed!

//another callback
const myFn = function(x) {
    return x - 100;
}

//main function
function maybe(number, predicate, callback) {
    if (predicate(number) === true) {
        //console.log('predicate === true');
        //console.log(callback(number));
        return callback(number);
    } else {
        return number;
    }
}



test(maybe(1, notZero, plusOne), 2);
test(maybe(0, notZero, plusOne), 0);

test(maybe(101, x => x > 100, myFn), 1);
test(maybe(99, x => x > 100, myFn), 99);

编辑:如下所述,maybe现在只能采用 2 个参数(谓词和回调),因为它现在返回一个参数为number. 这就是我一直在寻找的想法。

function maybe(predicate, callback) {

    return function (number) {
        if (predicate(number) === true) {
            return callback(number);
        } else {
            return number;
        }
    }
}

标签: javascriptcallbackhigher-order-functions

解决方案


这在技术上是不可能的。x在 的范围内被锁定在世界之外predicate。您无法将其从该函数中提取出来。

除此之外,正如您在代码中正确假设的那样,我们在逻辑上需要xpredicate&进行通信callback。否则,有什么意义maybe呢?

从那时起,您的解决方案就是极少数可能的解决方案之一。

你可以用咖喱更好地“装饰”它。这个想法与您的代码完全相同,但如果您这样做,您将能够完全使用 2 个参数调用最终函数。

const setMaybeBase => x => (predicate, callback) => predicate(x) ? callback(x) : x;

// use it later this way
const maybe42 = setMaybeBase(42);
maybe42(yourFn, yourFnTwo);

除非您传递给的参数是例如您要使用的复杂对象,否则这是一个巨大的过度杀伤力。setMaybeBase


或者,您可能会疯狂并使用函数来获取x

尽管如此,请始终记住,最简单的解决方案是最好的解决方案。

这是一个直接取自node.js repo的可能函数的真实示例:

function maybeCallback(cb) {

  if (typeof cb === 'function')

    return cb;



  throw new ERR_INVALID_CALLBACK(cb);

}

推荐阅读