javascript - JavaScript 中的多个箭头函数是什么意思?

标签 javascript reactjs ecmascript-6 arrow-functions

我一直在阅读一堆 React代码,我看到像这样我不明白的东西:

handleChange = field => e => {
  e.preventDefault();
  /// Do something here
}

最佳答案

那是一个curried function

首先,用两个参数检查这个函数......

const add = (x, y) => x + y
add(2, 3) //=> 5

这里又是柯里化(Currying)的形式……

const add = x => y => x + y

这里是没有箭头函数的相同1代码……

const add = function (x) {
  return function (y) {
    return x + y
  }
}

关注返回

以另一种方式形象化它可能会有所帮助。我们知道箭头函数是这样工作的——让我们特别注意返回值

const f = someParam => <b>returnValue</b>

所以我们的 add 函数返回一个 function – 我们可以使用括号来增加清晰度。 粗体 文本是函数 add

的返回值
const add = x => <b>(y => x + y)</b>

换句话说,一些数字的add返回一个函数

add(2) // returns (y => 2 + y)

调用柯里化(Currying)函数

所以为了使用我们的柯里化(Currying)函数,我们必须以不同的方式调用它......

add(2)(3)  // returns 5

这是因为第一个(外部)函数调用返回第二个(内部)函数。只有在我们调用第二个函数之后,我们才真正得到结果。如果我们将调用分开在两条线上,这一点会更加明显……

const add2 = add(2) // returns function(y) { return 2 + y }
add2(3)             // returns 5

将我们的新理解应用到您的代码中

related: ”What’s the difference between binding, partial application, and currying?”

好的,现在我们了解了它是如何工作的,让我们看看您的代码

handleChange = field => e => {
  e.preventDefault()
  /// Do something here
}

我们将从不使用箭头函数来表示它开始……

handleChange = function(field) {
  return function(e) {
    e.preventDefault()
    // Do something here
    // return ...
  };
};

但是,因为箭头函数在词法上绑定(bind) this,所以它实际上看起来更像这样......

handleChange = function(field) {
  return function(e) {
    e.preventDefault()
    // Do something here
    // return ...
  }.bind(this)
}.bind(this)

也许现在我们可以更清楚地看到它在做什么。 handleChange 函数正在为指定的字段 创建一个函数。这是一种方便的 React 技术,因为您需要在每个输入上设置自己的监听器才能更新您的应用程序状态。通过使用 handleChange 函数,我们可以消除所有会导致为每个字段设置 change 监听器的重复代码。酷!

1 这里我没必要词法绑定(bind)this因为原来的add函数不使用任何上下文,所以不重要在这种情况下保留它。


更多箭头

如有必要,可以对两个以上的箭头函数进行排序 -

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)函数能够做出令人惊讶的事情。下面我们看到 $ 被定义为带有两个参数的柯里化(Currying)函数,但在调用站点,我们似乎可以提供任意数量的参数。柯里化(Currying)是 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

部分应用

部分应用是一个相关的概念。它允许我们部分应用函数,类似于柯里化(Currying),除了函数不必以柯里化(Currying)形式定义 -

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 的工作演示 -

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 - JavaScript 中的多个箭头函数是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51748965/

相关文章:

javascript - 将选项卡设置为事件状态时,所有选项卡都会变为 false 算法 Meteor React

javascript - 如何从 chartjs 中隐藏零数据值?

javascript - 作为对象的一部分发送时无法读取 response.json()

javascript - 如何将具有许多状态变量的嵌套循环放入表中?

javascript - Meteor 中无限滚动实现的订阅行为

javascript - React 组件检查变量是否为空

javascript - jQuery 中 Uncaught ReferenceError

javascript - 如何使我的 php 变量可访问?

node.js - 这个 ReactRouter.match() 实现有什么问题?

javascript - 警告点击按钮的内部 HTML