简体   繁体   English

什么时候应该在 ES6 箭头函数中使用 return 语句

[英]When should I use a return statement in ES6 arrow functions

The new ES6 arrow functions say return is implicit under some circumstances:新的ES6 箭头函数return在某些情况下是隐式的:

The expression is also the implicit return value of that function.该表达式也是 function 的隐式返回值。

In what cases do I need to use return with ES6 arrow functions?在什么情况下我需要使用带有 ES6 箭头函数的return

Jackson has partially answered this in a similar question:杰克逊在一个类似的问题中部分回答了这个问题:

Implicit return, but only if there is no block.隐式返回,但前提是没有阻塞。

  • This will result in errors when a one-liner expands to multiple lines and the programmer forgets to add a return .当单行扩展为多行并且程序员忘记添加return时,这将导致错误。
  • Implicit return is syntactically ambiguous.隐式返回在语法上是模棱两可的。 (name) => {id: name} returns the object {id: name} ... right? (name) => {id: name}返回对象{id: name} ...对吗? Wrong.错误的。 It returns undefined .它返回undefined Those braces are an explicit block.这些大括号是一个显式块。 id: is a label. id:是一个标签。

I would add to this the definition of a block :我会添加一个的定义:

A block statement (or compound statement in other languages) is used to group zero or more statements.块语句(或其他语言中的复合语句)用于对零个或多个语句进行分组。 The block is delimited by a pair of curly brackets.该块由一对大括号分隔。

Examples :例子

// returns: undefined
// explanation: an empty block with an implicit return
((name) => {})() 

// returns: 'Hi Jess'
// explanation: no block means implicit return
((name) => 'Hi ' + name)('Jess')

// returns: undefined
// explanation: explicit return required inside block, but is missing.
((name) => {'Hi ' + name})('Jess')

// returns: 'Hi Jess'
// explanation: explicit return in block exists
((name) => {return 'Hi ' + name})('Jess') 

// returns: undefined
// explanation: a block containing a single label. No explicit return.
// more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label
((name) => {id: name})('Jess') 

// returns: {id: 'Jess'}
// explanation: implicit return of expression ( ) which evaluates to an object
((name) => ({id: name}))('Jess') 

// returns: {id: 'Jess'}
// explanation: explicit return inside block returns object
((name) => {return {id: name}})('Jess') 

I understand this rule-of-thumb ...我理解这个经验法则...

For functions that are effectively transforms (one-line-manipulations of arguments), return is implicit.对于有效转换的函数(参数的单行操作),return 是隐式的。

Candidates are:候选人是:

// square-root 
value => Math.sqrt(value)

// sum
(a,b) => a+b

For other operations (more than one-liners that require a block, return has to be explicit对于其他操作(需要块的多行,return 必须是显式的

There's another case here.这里还有一个案例。

For example, when writing a functional component in React, you can use parentheses to wrap implicitly returned JSX.例如,在 React 中编写函数式组件时,可以使用括号来包装隐式返回的 JSX。

const FunctionalComponent = () => (
  <div>
    <OtherComponent />
  </div>
);

Here's another case that gave me some trouble.这是另一个给我带来麻烦的案例。

// the "tricky" way
const wrap = (foo) => (bar) => {
  if (foo === 'foo') return foo + ' ' + bar;
  return 'nofoo ' + bar;
}

Here we define a function returning an anonymous function.The "tricky" bit is that the function body for the outer function (the part begining with (bar) => ...) visually looks like a "block", but it's not.这里我们定义了一个返回匿名函数的函数。“棘手”的一点是外部函数的函数体(以 (bar) => ... 开头的部分)在视觉上看起来像一个“块”,但事实并非如此。 Since it's not, implicit return kicks in.既然不是,隐式返回就开始了。

Here's how wrap would execute:以下是 wrap 的执行方式:

// use wrap() to create a function withfoo()
const withfoo = wrap('foo');
// returns: foo bar
console.log(withfoo('bar'));

// use wrap() to create a function withoutfoo()
const withoutfoo = wrap('bar');
// returns: nofoo bar
console.log(withoutfoo('bar'));

The way I unpacked this to make sure I understood it was to "unarrowify" the functions.我打开包装以确保我理解它的方式是“取消”功能。

Here's the semantic equivalent of the first code block, simply making the body of wrap() do an explicit return.这是第一个代码块的语义等价物,只是让 wrap() 的主体进行显式返回。 This definition produces the same results as above.此定义产生与上述相同的结果。 This is where the dots connect.这是点连接的地方。 Compare the first code block above with the one below, and it's clear that an arrow function itself is treated as an expression, not a block, and has the implied return .比较上面的第一个代码块和下面的代码块,很明显箭头函数本身被视为表达式,而不是块,并且具有隐含的 return

// the explicit return way
const wrap = (foo) => {
  return (bar) => {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  }
}

The fully unarrowified version of wrap would be like this, which while not as compact as the fat arrowed up version, seems a lot easier to comprehend. wrap 的完全非箭头版本是这样的,虽然不像胖箭头向上版本那么紧凑,但似乎更容易理解。

// the "no arrow functions" way
const wrap = function(foo) {
  return function(bar) {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  };
};

In the end, for others that may have to read my code, and future me, I think I'd prefer to go the non arrow version which can be comprehended visually at first glance, rather than the arrow one which takes a fair bit of thought (and in my case experimentation) to grok.最后,对于可能需要阅读我的代码的其他人,以及未来的我,我想我更愿意使用第一眼就可以理解的非箭头版本,而不是需要相当多的箭头版本想(在我的情况下是实验)去摸索。

Arrow functions allow you to have an implicit return: values are returned without having to use the return keyword.箭头函数允许您进行隐式返回:无需使用return关键字即可返回值。

It works when there is a on-line statement in the function body:它在函数体中有在线语句时起作用:

 const myFunction = () => 'test' console.log(myFunction()) //'test'

Another example, returning an object (remember to wrap the curly brackets in parentheses to avoid it being considered the wrapping function body brackets):另一个例子,返回一个对象(记得将花括号括在括号中以避免它被认为是包装函数体括号):

 const myFunction = () => ({value: 'test'}) console.log(myFunction()) //{value: 'test'}

Omitting the brackets {} and return keyword from an arrow function are ok if: (1) You wouldn't have any code (eg assignment statements) before the return statement and (2) You would be returning a single entity [Note: The single entity can be multiple lines.在以下情况下,可以从箭头函数中省略括号 {} 和 return 关键字:(1)在 return 语句之前您不会有任何代码(例如赋值语句),并且(2)您将返回单个实体 [注意:单个实体可以是多行。 If so, then all you need are regular parentheses() like the example below:如果是这样,那么您只需要常规括号(),如下例所示:

posts.map(post => (
  <li key={post.id}>
    {post.title}
  </li>
))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM