功能JavaScript:如何实现Function.prototype.not

Aus*_*yde 7 javascript functional-programming

我今天早些时候正在研究一些代码,当时我意识到,"嘿!如果我抽象出一个不是匿名函数的布尔的概念并且进入原型函数,那么这段代码会更简洁和语义化......"

考虑一个谓词生成器:

function equalTo(n) {
    return function(x) {
        return n==x;
    };
}
Run Code Online (Sandbox Code Playgroud)

所以你可以像这样使用它:

[1,2,3,4,1,2,3,4].filter(equalTo(2)) == [2,2]
Run Code Online (Sandbox Code Playgroud)

现在,我的想法是使谓词"反转":

Function.prototype.not = function() {
    //???
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以说:

[1,2,3,4,1,2,3,4].filter(equalTo(2).not) == [1,3,4,1,3,4]
Run Code Online (Sandbox Code Playgroud)

我对实现的第一次尝试可能非​​常天真:

Function.prototype.not = function () {
    return ! this(arguments);
}
Run Code Online (Sandbox Code Playgroud)

也许它为什么不起作用.

你将如何实现这个功能,为什么?

我只是试图围绕功能性想法,并且知道JavaScript足以知道它可以用来做到这一点,但不是如何.

SLa*_*aks 7

您的实施不会有多种原因:

  • 您需要返回一个函数,而不是布尔值.
  • 您应该按原样传递参数,而不是包装在数组中.
  • 您应该保留this调用该函数的上下文(关键字).

我会像这样实现它:

Function.prototype.not = function (context) {
    var func = this;
    return function() { return !func.apply(context || this, arguments); };
}
Run Code Online (Sandbox Code Playgroud)
  • 我返回一个匿名函数(function() { ... })
  • 我调用apply当前上下文中的实际参数调用原始函数.
  • (编辑)免费奖励:我添加了一个可选context参数,它将覆盖this回调.

  • 由于`not`是一个函数,你可以使用`equalTo(2).not()`来调用它. (3认同)