JavaScript的咖喱:什么是实际应用?(JavaScript curry: what are

2019-06-14 17:42发布

我不认为我已经grokked哗众取宠呢。 我知道它做什么,以及如何做到这一点。 我只是不能想一个情况,我会用它。

你是哪里在JavaScript中使用柯里(或者正在使用它的主库)? DOM操作或通用应用程序开发实例欢迎。

答案之一提到动画。 像功能slideUpfadeIn需要的元素作为参数,并通常是一个咖喱函数返回用默认的“动画功能”内置的高阶函数。 这是为什么不仅仅是一些默认应用更高-up功能更好?

是否有任何缺点,使用它?

由于这里要求是JavaScript的钻营一些很好的资源:

  • http://www.dustindiaz.com/javascript-curry/
  • 克罗克福德,道格拉斯(2008) 的JavaScript:好的部分
  • http://www.svendtofte.com/code/curried_javascript/ (需要绕道而行到ML所以从“在ML的速成课程”跳过整个部分,并在重新开始“怎样写咖喱的JavaScript”)
  • http://web.archive.org/web/20111217011630/http://blog.morrisjohns.com:80/javascript_closures_for_dummies
  • 如何关闭JavaScript的工作?
  • http://ejohn.org/blog/partial-functions-in-javascript (Resig的先生的钱按通常)
  • http://benalman.com/news/2010/09/partial-application-in-javascript/

我会添加更多的,因为他们在评论中出现。


因此,根据通常的答案,钻营和局部应用是方便的技术。

如果你经常“炼”用相同的配置称这是一个高层次的功能,可以咖喱(或使用Resig的部分)的更高级别的函数来创建简单,简洁的辅助方法。

Answer 1:

@Hank同性恋

为了响应EmbiggensTheMind的评论:

我想不出哪里实例的钻营 -by本身,就是在JavaScript中有用的; 它是用于将函数调用与多个参数成函数链的技术为每个呼叫的单个自变量来调用,但JavaScript的支持在一个函数调用多个参数。

在JavaScript的,我以为 - 它通常与部分应用程序相关联,尽管其他大多数实际的语言(不是演算)。 约翰Resig的解释它更好的 ,但要点是,有一个将被应用到两个或多个参数的一些逻辑,你只知道其中的一些参数的值(一个或多个)。

您可以使用部分应用程序/钻营解决这些已知值,并返回一个函数,只接受未知数,被调用后,当你确实有你要传递的价值观。 这提供了一个极好的方法,以避免重复自己,当你会被一遍又一遍的所有相同的价值观,但一个调用同一个JavaScript内置插件。 窃取约翰的例子:

String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );


Answer 2:

这里有一个有趣和实用的应用在使用JavaScript的闭包讨好的

 function converter(toUnit, factor, offset, input) { offset = offset || 0; return [((offset + input) * factor).toFixed(2), toUnit].join(" "); } var milesToKm = converter.curry('km', 1.60936, undefined); var poundsToKg = converter.curry('kg', 0.45460, undefined); var farenheitToCelsius = converter.curry('degrees C', 0.5556, -32); milesToKm(10); // returns "16.09 km" poundsToKg(2.5); // returns "1.14 kg" farenheitToCelsius(98); // returns "36.67 degrees C" 

这依赖于一个curry的扩展Function ,但你可以看到它仅使用apply (没有什么太花哨):

 Function.prototype.curry = function() { if (arguments.length < 1) { return this; //nothing to curry with - return function } var __method = this; var args = toArray(arguments); return function() { return __method.apply(this, args.concat([].slice.apply(null, arguments))); } } 


Answer 3:

我发现,像Python的功能functools.partial更有用在JavaScript:

function partial(fn) {
  return partialWithScope.apply(this,
    Array.prototype.concat.apply([fn, this],
      Array.prototype.slice.call(arguments, 1)));
}

function partialWithScope(fn, scope) {
  var args = Array.prototype.slice.call(arguments, 2);
  return function() {
    return fn.apply(scope, Array.prototype.concat.apply(args, arguments));
  };
}

你为什么要使用它? 要使用一个常见的情况是,当你要绑定this函数中的一个值:

var callback = partialWithScope(Object.function, obj);

现在,当回调被调用, this指向obj 。 这是事件的情况下非常有用或以节省一些空间,因为它通常使代码更短。

钻营类似于局部区别在于所述钻营返回功能只是接受一个参数(据我理解)。



Answer 4:

汉克同性恋同意 - 这是一个在某些真正的函数式编程语言非常有用的 - 因为它是一个必要组成部分。 例如,在Haskell你根本无法采取多个参数的函数 - 你不能这样做,在纯函数式编程。 你把一个PARAM在同一时间,建立你的函数。 在JavaScript中这是完全没有必要,尽管像“转换器”做作的例子。 下面是同一转换代码,而无需钻营:

var converter = function(ratio, symbol, input) {
    return (input*ratio).toFixed(2) + " " + symbol;
}

var kilosToPoundsRatio = 2.2;
var litersToUKPintsRatio = 1.75;
var litersToUSPintsRatio = 1.98;
var milesToKilometersRatio = 1.62;

converter(kilosToPoundsRatio, "lbs", 4); //8.80 lbs
converter(litersToUKPintsRatio, "imperial pints", 2.4); //4.20 imperial pints
converter(litersToUSPintsRatio, "US pints", 2.4); //4.75 US pints
converter(milesToKilometersRatio, "km", 34); //55.08 km

我想不好道格拉斯克罗克福德,在“JavaScript的:好零件”,给了历史和实际使用哗众取宠,而不是他的offhanded言论的一些提。 对于读取后的时间最长,我猛然一惊,直到我学习函数式编程和实现这就是它来自何处。

经过一番更多的思考,我断定有一个有效的使用案例在JavaScript柯里:如果你想使用使用JavaScript纯函数式编程技术编写。 似乎是一个罕见的用例虽然。



Answer 5:

下面是一个例子。

我插装了一堆使用jQuery领域的,所以我可以看到哪些用户也最多。 代码如下所示:

$('#foo').focus(trackActivity);
$('#foo').blur(trackActivity);
$('#bar').focus(trackActivity);
$('#bar').blur(trackActivity);

(对于非JQuery的用户,我是说,任何时候一对夫妇领域得到或失去焦点,我希望trackActivity()函数被调用。我还可以使用匿名函数,但我不得不重复它4次,所以我把它并把它命名。)

现在事实证明,需要进行不同处理的领域之一。 我希望能够通过一个参数,在给我们的跟踪基础设施要传递这些调用之一。 随着钻营,我可以。



Answer 6:

这已经不是什么魔法或者什么...只是匿名函数一个愉快的简写。

partial(alert, "FOO!")等同于function(){alert("FOO!");}

partial(Math.max, 0)对应于function(x){return Math.max(0, x);}

该调用部分( MochiKit术语。我想一些其他的库给功能,这做同样的事情.curry方法)会略有更好,比匿名函数噪音更小。



Answer 7:

至于图书馆使用它,总是有功能 。

什么时候在JS有用吗? 可能是相同的时候,它是其他现代语言是有用的,但唯一的一次我可以看到自己使用它是与部分应用程序相结合。



Answer 8:

我要说的是,最有可能,在JS的所有动画库使用钻营。 而不是通过为每个调用一组受影响的元素和功能,描述元素应该如何表现,更高阶的功能,以确保所有的时序的东西,它通常更容易为客户释放,作为公共API一些功能,例如“效果基本show”,“淡入”,它只接受元素作为参数,而只是一些咖喱函数返回用默认的“动画功能”内置的高阶函数。



Answer 9:

JavaScript函数被调用其他功能的语言LAMDA。 它可以用来组成一个新的API(更强大或complext功能)基于其他开发人员的简单的输入。 库里只是其中的技术之一。 您可以使用它来创建一个简单的API调用复杂的API。 如果你是谁使用简化的API(例如,你使用jQuery做简单的操作)的develper,你并不需要使用咖喱。 但是,如果你要创建的简化的API,咖喱是你的朋友。 你必须写一个JavaScript框架(如jQuery,mootools的)或库,那么你可以体会到它的威力。 我写了一个增强的咖喱功能,在http://blog.semanticsworks.com/2011/03/enhanced-curry-method.html 。 你并不需要的咖喱的方法做钻营,它只是帮助做钻营,但你总是可以做手工写一个函数A(){}返回另一个函数B(){}。 为了使它更有趣,使用功能B()返回另一个函数C()。



Answer 10:

我知道它的旧线,但我必须证明这是如何正在JavaScript库中使用:

我会用lodash.js库来具体描述这些概念。

例:

var fn = function(a,b,c){ 
return a+b+c+(this.greet || ‘'); 
}

部分应用程序:

var partialFnA = _.partial(fn, 1,3);

柯里:

var curriedFn = _.curry(fn);

捆绑:

var boundFn = _.bind(fn,object,1,3 );//object= {greet: ’!'}

用法:

curriedFn(1)(3)(5); // gives 9 
or 
curriedFn(1,3)(5); // gives 9 
or 
curriedFn(1)(_,3)(2); //gives 9


partialFnA(5); //gives 9

boundFn(5); //gives 9!

区别:

柯里后,我们得到不带参数的新功能预先绑定。

部分应用程序后,我们得到这势必有一些参数预先绑定的功能。

在结合我们可以结合将被用来取代“这个”,如果没有任何约束函数的缺省值将是窗口范围的上下文。

提醒:没有必要推倒重来。 部分应用程序/绑定/钻营有很大关系。 你可以看到上面的差异。 在任何地方使用这个意义上,人们会认识到你在理解问题没有做什么,再加上你将不得不使用更少的代码。



Answer 11:

我认为,有时候你想拿到球通过创建一个伪功能,将始终充满在第一个参数的值滚动幸运的是,我遇到了一个全新的JavaScript库称为jPaq(H TTP:// jpaq.org/ ),其提供了这种功能。 关于图书馆的最好的事情是,你可以下载自己的身材只包含你需要的代码的事实。



Answer 12:

我只是写了jPaq例子显示了咖喱功能的一些很酷的应用。 看看这里: 钻营向上字符串函数



Answer 13:

只是想补充一些资源Functional.js:

讲座/会议解释一些应用http://www.youtube.com/watch?v=HAcN3JyQoyY

更新Functional.js库: https://github.com/loop-recur/FunctionalJS一些不错的帮手(对不起新来的,没有信誉:P)/环易复发/ PreludeJS

我一直在使用这个库最近减少了很多在JS IRC客户端助手库重复。 这是伟大的东西 - 真正帮助清理和简化代码。

此外,如果性能成为一个问题(但这种LIB是相当轻),它很容易只是重写使用本机的功能。



Answer 14:

您可以使用本机绑定,以便快速,一条线解决方案

 function clampAngle(min, max, angle) { var result, delta; delta = max - min; result = (angle - min) % delta; if (result < 0) { result += delta; } return min + result; }; var clamp0To360 = clampAngle.bind(null, 0, 360); console.log(clamp0To360(405)) // 45 



Answer 15:

另一个刺它,从承诺的工作。

(免责声明:即使有JS小白,从Python世界的到来, 钻营 ,不使用所有的东西,但它可以派上用场之际所以我在那儿剽窃功能钻营-见链接)

首先,我开始用Ajax调用。 我有一些具体的处理上做的成功,但失败,我只是想给用户,调用的东西产生了一些错误的反馈。 在我实际的代码,我显示的引导面板错误的反馈,但只是用记录在这里。

我修改我的直播网址,使这个失败。

function ajax_batch(e){
    var url = $(e.target).data("url");

    //induce error
    url = "x" + url;

    var promise_details = $.ajax(
        url,
        {
            headers: { Accept : "application/json" },
            // accepts : "application/json",
            beforeSend: function (request) {
                if (!this.crossDomain) {
                    request.setRequestHeader("X-CSRFToken", csrf_token);
                }
        },
        dataType : "json",
        type : "POST"}
    );
    promise_details.then(notify_batch_success, fail_status_specific_to_batch);
}

现在,这里为了告诉了一批不合格的用户,我需要写在错误处理程序的信息,因为所有这越来越是从服务器的响应。

我仍然只有可在编码时的信息 - 在我的情况我有很多可能的批次,但我不知道哪一个失败WO解析有关失败的URL服务器的响应。

function fail_status_specific_to_batch(d){
    console.log("bad batch run, dude");
    console.log("response.status:" + d.status);
}

我们开始做吧。 控制台输出为:

安慰:

bad batch run, dude utility.js (line 109) response.status:404

现在,让我们改变的事情了一下,使用可重复使用的一般故障处理程序,还一个是在运行时令行禁止同时与已知的代码时调用上下文,并且可以从事件中运行时信息。

    ... rest is as before...
    var target = $(e.target).text();
    var context = {"user_msg": "bad batch run, dude.  you were calling :" + target};
    var contexted_fail_notification = curry(generic_fail, context); 

    promise_details.then(notify_batch_success, contexted_fail_notification);
}

function generic_fail(context, d){
    console.log(context);
    console.log("response.status:" + d.status);
}

function curry(fn) {
     var slice = Array.prototype.slice,
        stored_args = slice.call(arguments, 1);
     return function () {
        var new_args = slice.call(arguments),
              args = stored_args.concat(new_args);
        return fn.apply(null, args);
     };
}

安慰:

Object { user_msg="bad batch run, dude. you were calling :Run ACL now"} utility.js (line 117) response.status:404 utility.js (line 118)

更一般地,给定的回调使用率有多普遍在JS,钻营好像有一个非常有用的工具。

https://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/ http://www.drdobbs.com/open-source/currying-and-partial-functions-in- javasc / 231001821?PGNO = 2



文章来源: JavaScript curry: what are the practical applications?