简体   繁体   English

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

[英]Functional JavaScript: how to implement Function.prototype.not

I was working on some code earlier today, when I realized, "Hey! This code would be more concise and semantic if I abstracted the idea of a boolean not out of an anonymous function and into a prototype function..." 我今天早些时候正在研究一些代码,当时我意识到,“嘿!如果我抽象出一个不是匿名函数的布尔的想法并且进入原型函数,那么这段代码会更简洁和语义......”

Consider a predicate generator: 考虑一个谓词生成器:

function equalTo(n) {
    return function(x) {
        return n==x;
    };
}

So you can use it like so: 所以你可以像这样使用它:

[1,2,3,4,1,2,3,4].filter(equalTo(2)) == [2,2]

Now, my idea is to make a predicate "inverser": 现在,我的想法是使谓词“反转”:

Function.prototype.not = function() {
    //???
}

So that you can say: 这样你就可以说:

[1,2,3,4,1,2,3,4].filter(equalTo(2).not) == [1,3,4,1,3,4]

My first stab at the implementation was probably very naive: 我对实现的第一次尝试可能非​​常天真:

Function.prototype.not = function () {
    return ! this(arguments);
}

And probably why it didn't work. 也许它为什么不起作用。

How would you implement this function, and why? 你将如何实现这个功能,为什么?

I'm just trying to wrap my head around functional ideas, and know JavaScript well enough to know it can be used to do this, but just not how. 我只是试图围绕功能性想法,并且知道JavaScript足以知道它可以用来做到这一点,但不是如何。

Your implementation won't work for several reasons: 您的实施不会有多种原因:

  • You need to return a function, not a boolean. 您需要返回一个函数,而不是布尔值。
  • You should pass the arguments as-is, not wrapped in an array. 您应该按原样传递参数,而不是包装在数组中。
  • You should preserve the context ( this keyword) that the function would have been called in. 您应该保留调用该函数的上下文( this关键字)。

I would implement it like this: 我会像这样实现它:

Function.prototype.not = function (context) {
    var func = this;
    return function() { return !func.apply(context || this, arguments); };
}
  • I return an anonymous function ( function() { ... } ) 我返回一个匿名函数( function() { ... }
  • I call apply to call the original function in the current contexts with the actual arguments. 我调用apply来调用当前上下文中的原始函数和实际参数。
  • ( EDIT ) Free bonus: I added an optional context parameter which will override this for the callback. 编辑 )免费奖金:我添加了一个可选context参数,将覆盖this回调。

I would probably do it like so (but perhaps with some sort of namespacing): 我可能会这样做(但也许有某种命名空间):

function not (x) {
  return !x;
}

function id (x) {
  return x;
}

function compose (/*funcs*/) {
  var args = arguments.length
    ? Array.prototype.slice.call (arguments)
    : [id]
    ;
  return function () {
    var val = args [args.length - 1].apply (null, arguments);
    for (var i = args.length - 2; i >= 0; --i) {
      val = args [i] (val);
    }
    return val;
  };
}

[1,2,3,4,1,2,3,4].filter (compose (not, equalTo (2)));

Using your idea: 用你的想法:

function equalTo(n) {
    var fn = function(x) {
        return n == x;
    };
    fn.not = function(x) {
        return n != x; // use this for simpler conditions
        return !fn.apply(this, arguments); // use this for more complex logic
    }
    return fn;
}

So your example would work: 所以你的例子会起作用:

[1,2,3,4,1,2,3,4].filter(equalTo(2).not) == [1,3,4,1,3,4]

Edit : You can write a helper function (better name to be found) so not doesn't need to be redefined every time: 编辑 :你可以写一个辅助函数(可以找到更好的名字),所以not也不需要每次都重新定义:

function generateFnWithNot(fn) {
    return function () {
        var f = fn.apply(this, arguments);
        f.not = function () {
            return !f.apply(this, arguments);
        }
        return f;
    };
}

So when you're defining your functions, you can define them as normal with the exception of wrapping a generateFnWithNot call: 因此,当您定义函数时,除了包装generateFnWithNot调用之外,您可以将它们定义为正常:

var equalTo = generateFnWithNot(function (n) {
    return function (x) {
        return n == x;
    };
});

equalTo(5) // resolves to function () { return n == 5; }
equalTo(5).not // resolves to function () { return n != 5; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在javascript中实现二维数组的原型函数? - How to implement prototype function with 2 dimensional array in javascript? 如何通过原型在JavaScript中实现超级机制? - How to implement super mechanism in javascript through prototype? 如何使用原型框架在Javascript中实现OO? - How to implement the OO in Javascript using prototype framework? 如何在 JavaScript 中使用“纯”函数式编程实现记忆化 - How to implement memoization with "pure" Functional Programming in JavaScript 如何在JavaScript中向Function.prototype添加函数? - How to add a function to Function.prototype in JavaScript? 如何将原型 jquery function 转换为 javascript 原型 ZC1C425268E68385D1AB5074C141 - How to convert a prototype jquery function to javascript prototype function JavaScript:如何使用参数制作原型函数 - JavaScript: How to make a prototype function with parameters Javascript中基于函数原型的编程的语义 - Semantics of functional prototype-based programming in Javascript Javascript *不是函数(原型函数) - Javascript * is not a function (prototype function) 如何使用javascript在函数式编程中使用IO和Either函数实现线性流? - How to implement linear flow with IO and Either functors in functional programming with javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM