Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
414 views
in Technique[技术] by (71.8m points)

javascript - javascript中的多个箭头功能是什么意思?(What do multiple arrow functions mean in javascript?)

I have been reading a bunch of react code and I see stuff like this that I don't understand:

(我一直在读一堆react代码,我看到一些我不明白的东西:)

handleChange = field => e => {
  e.preventDefault();
  /// Do something here
}
  ask by jhamm translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

That is a curried function

(那是一个咖喱函数)

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 1 code without arrow functions …

(这是没有箭头功能的相同1个代码……)

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

Focus on return

(专注于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)

So our add function returns a function – we can use parentheses for added clarity.

(因此,我们的add函数返回一个函数 –我们可以使用括号来增加清晰度。)

The bolded text is the return value of our function add

(粗体字是我们函数add的返回值)

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

In other words add of some number returns a function

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

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

Calling curried functions

(调用咖喱函数)

So in order to use our curried function, we have to call it a bit differently …

(因此,为了使用我们的curried函数,我们必须对其进行一些不同的调用……)

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

Applying our new understanding to your code

(将我们的新知识应用于您的代码)

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

(相关: “绑定,部分应用和柯林有什么区别?”)

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 ...
  };
};

However, because arrow functions lexically bind this , it would actually look more like this …

(但是,由于arrow函数用词法绑定了this ,因此实际上看起来更像这样……)

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

Maybe now we can see what this is doing more clearly.

(也许现在我们可以更清楚地看到它在做什么。)

The handleChange function is creating a function for a specified field .

(handleChange函数正在为指定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.

(这是一种方便的React技术,因为您需要在每个输入上设置自己的侦听器以更新您的应用程序状态。)

By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field.

(通过使用handleChange函数,我们可以消除所有重复的代码,这些代码将导致为每个字段设置change侦听器。)

Cool!

(凉!)

1 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.

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


Even more arrows

(甚至更多的箭)

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

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

(部分申请)

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 -

(它允许我们部分地应用函数,类似于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

Here's a working demo of partial you can play with in your own browser -

(这是您可以在自己的浏览器中播放的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"> 


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...