javascript 代码
by Rick Henry
由里克·亨利(Rick Henry)
如何使用部分应用程序来改善JavaScript代码 (How to use partial application to improve your JavaScript code)
利用这种功能性技术可以使您的代码更加优雅 (Making use of this functional technique can make your code more elegant)
Functional programming gives us techniques to solve problems in our code. One of these, partial application, is a little tricky to understand but it can allow us to write less of it (sounds interesting, right?).
函数式编程为我们提供了解决代码中问题的技术。 其中之一是部分应用程序,要理解它有些棘手,但可以让我们编写更少的代码(听起来很有趣,对吧?)。
它是什么? (What is it?)
Partial application starts with a function. We take this function and create a new one with one or more of its arguments already “set” or partially applied. This sounds odd, but it will reduce the number of parameters needed for our functions.
部分应用程序从一个函数开始。 我们采用此功能并创建一个新的函数,其中一个或多个参数已被“设置”或部分应用 。 这听起来很奇怪,但是它将减少我们功能所需的参数数量。
Let’s give some context around when we could use partial application:
让我们给出一些何时可以使用部分应用程序的上下文:
const list = (lastJoin, ...items) => { const commaSeparated = items.slice(0,-1).join(", "); const lastItem = items.pop(); return `${commaSeparated} ${lastJoin} ${lastItem}`;}
This little function takes in a single word, lastJoin
, and an arbitrary number of items
. Initially, list
declares a commaSeparated
variable. This variable stores a comma separated joined array of all the elements except the last. On the next line we store the last item in items
in a lastItem
variable. The function then returns using a string template.
这个小函数接受一个单词lastJoin
和任意数量的items
。 最初, list
声明一个commaSeparated
变量。 此变量存储除最后一个元素外的所有元素的逗号分隔联接数组。 在下一行中,我们将最后一项存储在lastItem
变量的items
中。 然后,该函数使用字符串模板返回。
The function then returns the items
, as a string, in list format. For example:
然后,该函数以列表格式以字符串形式返回items
。 例如:
list("and", "red", "green", "blue"); // "red, green and blue"list("with", "red", "green", "blue"); // "red, green with blue"list("or", "red", "green", "blue"); // "red, green or blue"
Our list
function allows us to create lists when we want. Each type of list we create, “and”, “with”, “or” is a specialisation of the general list
function. Wouldn’t it be nice if they could be functions of their own?!
我们的list
功能使我们可以在需要时创建列表。 我们创建的每种类型的列表“ and”,“ with”,“ or”是常规list
功能的特化。 如果它们可以成为自己的功能不是很好吗?
如何使用部分应用程序 (How to use partial application)
This is where partial application can help. For example, to make a listAnd
function, we “set” (or partially apply) the lastJoin
argument to be “and”. The result of doing this means we can invoke our partially applied function like this:
这是部分应用程序可以提供帮助的地方。 例如,要制作一个listAnd
函数,我们将lastJoin
参数“设置”(或部分应用 )为“ and”。 这样做的结果意味着我们可以像这样调用部分应用的函数:
listAnd("red", "green", "blue"); // "red, green and blue"
It doesn’t need to stop there either. We can make many specialised functions by partially applying an argument to our list function:
它也不需要停在那儿。 我们可以通过将一个参数部分应用到列表函数来创建许多专门的函数:
listOr("red", "green", "blue"); // "red, green or blue"listWith("red", "green", "blue"); // "red, green with blue"
To do this, we need to create a partial
utility function:
为此,我们需要创建一个partial
实用程序函数:
const partial = (fn, firstArg) => { return (...lastArgs) => { return fn(firstArg, ...lastArgs); }}
This function takes a function fn
as it’s first parameter and firstArg
as its second. It returns a brand new function with one parameter, lastArgs
. This gathers up the passed in arguments.
此函数将函数fn
作为其第一个参数并将firstArg
作为其第二个参数。 它返回带有一个参数lastArgs
全新函数。 这收集了传入的参数。
Now to make our listAnd
function we invoke partial
passing in our list
function and our last join word:
现在要创建listAnd
函数,我们将partial
传递传入list
函数和最后一个listAnd
:
const listAnd = partial(list, "and");
Our listAnd
function now only takes an arbitrary list of items. This function when invoked will, in turn, invoke the passed in list
function. We can see that it will be passed “and” as the first argument and the gathered lastArgs
thereafter.
现在,我们的listAnd
函数仅接受任意项目列表。 反之,此函数将调用传入的list
函数。 我们可以看到它将作为第一个参数传递“和”,然后将其作为聚集的lastArgs
。
We’ve now created a partially applied function. We can use this specialised function over and over again in our program:
现在,我们创建了部分应用的函数。 我们可以在程序中反复使用此专门功能:
listAnd("red", "green", "blue"); // "red, green and blue"
更进一步 (Taking it further)
The partial
function we created is to illustrate how partial application works. There are some great functional JavaScript libraries available which have this utility built in, such as Ramda JS.
我们创建的partial
函数是为了说明部分应用程序是如何工作的。 有一些内置了此实用程序的出色的功能JavaScript库,例如Ramda JS 。
It’s worth noting that even if you are new to partial application as a concept there is every chance you have been using it. If you have ever used the .bind()
method on a function this is an example of partial application. It’s common practice to pass this
into bind to set its context. Under the hood it’s partially applying this
and returning a new function.
值得注意的是,即使您不完全了解部分应用程序,也有使用它的各种可能。 如果您曾经在函数上使用过.bind()
方法,则这是部分应用程序的示例。 通常this
方法传递给bind来设置其上下文。 在后台,它部分地应用了this
并返回了一个新函数。
javascript 代码