JavaScript中的多箭头函数指什么?

14 浏览
0 Comments

JavaScript中的多箭头函数指什么?

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

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

admin 更改状态以发布 2023年5月23日
0
0 Comments

简述

这是一种以简短的方式编写返回另一个函数的函数。

const handleChange = field => e => {
  e.preventDefault()
  // Do something here
}
// is equal to 
function handleChange(field) {
  return function(e) {
    e.preventDefault()
    // Do something here
  }
}

动机

在某些情况下,我们需要传递额外的变量给一个带有固定参数的回调函数,但不希望使用全局变量。

例如,我们有一个按钮有一个onClick回调函数,我们想要传递一个变量,比如id,但onClick只接受一个参数event,这就使得我们无法同时传递idevent

const handleClick = (event, id) {
  event.preventDefault()
  // Dispatch some delete action by passing record `id`
}

这是不行的。

解决方法是编写一个返回另一个函数的函数,并将id放在其变量范围内,而不使用全局变量:

const handleClick = id => event {
  event.preventDefault()
  // Dispatch some delete action by passing record `id`
}
const Confirm = props => (
    

Are you sure to delete?

函数组合

多个箭头函数也被称为“柯里化函数”,用于函数组合。

import {compose} from 'redux'
import {store} from './store.js'
const pickSelectedUser = props => {
  const {selectedName, users} = props
  const foundUser = users.find(user => user.name === selectedName)
  return foundUser.id
}
const deleteUser = userId => event => {
  event.preventDefault()
  store.dispatch({
    type: `DELETE_USER`,
    userId,
  })
}
// The compose function creates a new function that accepts a parameter.
// The parameter will be passed throw the functions from down to top.
// Each function will change the value and pass it to the next function
// By changing value it was not meant a mutation
const handleClick = compose(
  deleteUser,
  pickSelectedUser,
)
const Confirm = props => (
    

Are you sure to delete?

0
0 Comments

这是一个< a href="https://en.wikipedia.org/wiki/Currying" rel="noreferrer">柯里化函数

首先,让我们看一下这个具有两个参数的函数...

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

这是一个柯里化形式的函数...

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

这里是同样的代码,但没有箭头函数...

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


关注return

另外一种方式来观察这个问题可能会有所帮助。 我们知道箭头函数是如何工作的-让我们特别关注返回值

const f = someParam => returnValue

因此,我们的add函数返回一个函数-我们可以使用括号来增加清晰度。 粗体文本是我们函数add的返回值。

const add = x => (y => x + y)

换句话说,add与某个数字一起返回一个函数。

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


调用柯里化函数

为了使用我们的柯里化函数,我们必须稍微不同地调用它...

add(2)(3)  // returns 5

这是因为第一(外部)函数调用会返回第二(内部)函数。 只有在我们调用第二个函数之后,我们才实际得到结果。 如果我们在两行上分别调用,则更加明显...

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


将新的理解应用于您的代码

相关:“绑定、部分应用和柯里化之间有什么区别?”

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

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

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

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

然而,由于箭头函数在词法上绑定了 this,因此实际上看起来更像是这样的...

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

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

1 这里我不必词法绑定 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

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

偏函数应用

部分应用是一个相关的概念。它允许我们部分地应用函数,类似于柯里化,但函数不必定义为柯里化形式——

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))


0