问题描述
我一直在阅读一堆 React 代码,我看到了这样的东西我不明白:
I have been reading a bunch of React code and I see stuff like this that I don't understand:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
推荐答案
那是一个 柯里化函数
首先,用两个参数检查这个函数…
First, examine this function with two parameters …
const add = (x, y) => x + y
add(2, 3) //=> 5
这里又是咖喱饭…
Here it is again in curried form …
const add = x => y => x + y
这是没有箭头函数的相同代码…
Here is the same code without arrow functions …
const add = function (x) {
return function (y) {
return x + y
}
}
专注于return
以另一种方式将其可视化可能会有所帮助.我们知道箭头函数是这样工作的——让我们特别注意返回值.
It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.
const f = someParam => returnValue
所以我们的 add
函数返回一个 function - 我们可以使用括号来增加清晰度.粗体文本是我们函数add
So our add
function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add
const add = x => (y => x + y)
换句话说add
某个数字返回一个函数
In other words add
of some number returns a function
add(2) // returns (y => 2 + y)
调用柯里化函数
所以为了使用我们的柯里化函数,我们必须用不同的方式调用它…
So in order to use our curried function, we have to call it a bit differently …
add(2)(3) // returns 5
这是因为第一个(外部)函数调用返回第二个(内部)函数.只有在我们调用第二个函数之后,我们才能真正得到结果.如果我们将两行的调用分开,这一点会更加明显 …
This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
将我们的新理解应用到您的代码中
好的,现在我们了解了它的工作原理,让我们看看您的代码
OK, now that we understand how that works, let's look at your code
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
我们将从不使用箭头函数的情况下表示它开始…
We'll start by representing it without using arrow functions …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
然而,因为箭头函数在词法上绑定了this
,它实际上看起来更像这样…
However, because arrow functions lexically bind this
, it would actually look more like this …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
也许现在我们可以更清楚地看到这是做什么的.handleChange
函数正在为指定的 field
创建一个函数.这是一种方便的 React 技术,因为您需要在每个输入上设置自己的侦听器以更新应用程序状态.通过使用 handleChange
函数,我们可以消除所有会导致为每个字段设置 change
侦听器的重复代码.酷!
Maybe now we can see what this is doing more clearly. The handleChange
function is creating a function for a specified field
. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange
function, we can eliminate all the duplicated code that would result in setting up change
listeners for each field. Cool!
这里我不用词法绑定this
,因为原来的add
函数没有使用任何上下文,所以不重要在这种情况下保留它.
Here I did not have to lexically bind this
because the original add
function does not use any context, so it is not important to preserve it in this case.
更多箭头
如有必要,可以对两个以上的箭头函数进行排序 -
More than two arrow functions can be sequenced, if necessary -
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
柯里化函数能够产生令人惊奇的东西.下面我们看到 $
被定义为一个带有两个参数的柯里化函数,但在调用点,它似乎可以提供任意数量的参数.Currying 是 arity -
Curried functions are capable of surprising things. Below we see $
defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
部分申请
部分应用是一个相关的概念.它允许我们部分应用函数,类似于柯里化,除了函数不必以柯里化形式定义 -
Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
这是一个 partial
的工作演示,您可以在自己的浏览器中使用 -
Here's a working demo of partial
you can play with in your own browser -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
这篇关于JavaScript 中的多个箭头函数是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!