Dav*_*lan 171 javascript function currying partial-application
我不认为我已经讨好了.我理解它的作用,以及如何做到这一点.我想不出我会用它的情况.
你在JavaScript中使用currying(或者使用它的主要库在哪里)?欢迎DOM操作或一般应用程序开发示例.
其中一个答案提到了动画.函数如slideUp,fadeIn将元素作为参数,通常是一个curried函数,返回高阶函数,内置默认的"动画函数".为什么这比仅使用某些默认值更高的函数更好?
使用它有什么缺点吗?
根据要求,这里有一些关于JavaScript currying的好资源:
我会在评论中添加更多内容.
因此,根据答案,currying和部分应用一般是便利技术.
如果您经常通过使用相同配置调用高级函数来"精炼"高级函数,则可以使用更高级别的函数来设置(或使用Resig的部分)来创建简单,简洁的帮助器方法.
Pri*_*ERO 112
以下是使用闭包的JavaScript中currying的一个有趣且实用的用法:
Run Code Online (Sandbox Code Playgroud)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(没什么太花哨):
Run Code Online (Sandbox Code Playgroud)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))); } }
Han*_*Gay 33
@Hank Gay
回应EmbiggensTheMind的评论:
我想不出一个实例,其中curry -by本身 - 在JavaScript中很有用; 它是一种将具有多个参数的函数调用转换为函数调用链的技术,每个调用都有一个参数,但JavaScript在单个函数调用中支持多个参数.
在JavaScript中 - 我假设大多数其他实际语言(不是lambda演算) - 它通常与部分应用程序相关联.John Resig 更好地解释了它,但要点是有一些逻辑将应用于两个或多个参数,并且您只知道其中一些参数的值.
您可以使用部分应用程序/ currying来修复这些已知值并返回仅接受未知数的函数,以便在您实际拥有要传递的值时调用.这提供了一种很好的方法来避免重复自己,当你一直使用所有相同的值而一次调用相同的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" );
Run Code Online (Sandbox Code Playgroud)
我发现类似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));
};
}
Run Code Online (Sandbox Code Playgroud)
你为什么要用它?要使用此this功能的常见情况是,您希望将函数绑定到值:
var callback = partialWithScope(Object.function, obj);
Run Code Online (Sandbox Code Playgroud)
现在,当调用回调时,this指向obj.这在事件情况下很有用,或者节省一些空间,因为它通常会缩短代码.
Currying类似于partial,不同之处在于currying返回的函数只接受一个参数(据我所知).
同意Hank Gay - 它在某些真正的函数式编程语言中非常有用 - 因为它是必要的部分.例如,在Haskell中,您根本无法将多个参数带到函数中 - 您无法在纯函数式编程中执行此操作.你一次拿一个参数并建立你的功能.在JavaScript中,尽管有像"转换器"这样的人为例子,但它根本就没有必要.这是相同的转换器代码,无需curry:
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
Run Code Online (Sandbox Code Playgroud)
我非常希望Douglas Crockford在"JavaScript:The Good Parts"中提到过currying的历史和实际使用,而不是他的不和之言.在读完之后的最长时间里,我感到很困惑,直到我学习功能编程并意识到它来自哪里.
经过一番思考之后,我认为在JavaScript中有一个有效的用例:如果你试图使用JavaScript编写纯函数式编程技术.看起来像一个罕见的用例.
考虑filter功能。并且您想为其编写一个回调。
let x = [1,2,3,4,5,6,7,11,12,14,15];
let results = x.filter(callback);
Run Code Online (Sandbox Code Playgroud)
假设只想输出偶数,所以:
let callback = x => x % 2 === 0;
Run Code Online (Sandbox Code Playgroud)
现在想象我们想要实现callback这样的,根据场景,它输出高于某个阈值的偶数(这样的数字应该是可配置的)。
我们不能轻易地将这样的阈值数字作为callback函数的参数,因为filter调用callback并默认传递它数组元素和索引。
你会如何实施这个?
这是柯里化的一个很好的用例:
let x = [1,2,3,4,5,6,7,11,12,14,15];
let results = x.filter(callback);
Run Code Online (Sandbox Code Playgroud)