何时应在es6 Arrow Functions中使用`return`?


Answers:


261

杰克逊在一个类似的问题中部分回答了这个问题:

隐式返回,但仅当没有块时才返回。

  • 当单线扩展到多行并且程序员忘记添加时,这将导致错误return
  • 隐式返回在语法上是模棱两可的。(name) => {id: name}返回对象{id: name}...对吗?错误。它返回undefined。这些括号是一个明确的块。id:是一个标签。

我会在此添加一个的定义:

块语句(或其他语言的复合语句)用于将零个或多个语句分组。该块由一对大括号分隔。

例子

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

我没有这种语法..您是在使用沿海类创建类,然后使用一个参数('Jess')调用隐式构造函数吗?我以为你
会这样做

3
@MichaelDausmann这是一个箭头函数,具有一个参数,name该函数用括号括起来并用一个参数“ Jess”调用。在=>和之间的代码)('Jess')分别是箭头函数的主体。将其视为形式的立即调用函数表达式的简称(function (name) { return { id: name } })('Jess')
Russ Cam

非常有用!帮助您发现Promises.all中所有问题,这些问题都使用箭头函数映射到项目上,您会注意到,如果没有返回任何值来映射带有箭头函数的数组,您是否会得到未定义的数组。
杰伊·沙

将隐式返回系统化为箭头函数的弊端是什么?就像coffeescript一样...(尽管我不喜欢coffeescript)
Augustin Riedinger

4
明确地说,似乎是因为JS解析器不知道是期望表达式(例如包含对象常量的表达式{})还是,所以假定a { }表示块。这意味着,当它看到时id: name,它认为它id:是一个创建标签的表达式(这是JS的一种非常不常用的功能,它处理流控制并使用:),然后name下面id:是一个仅包含变量的单独语句name(&什么也没做)。
iono '18年

17

我了解此经验法则...

对于有效转换的函数(参数的单行处理),返回值是隐式的。

候选人是:

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

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

对于其他操作(不止一个衬里需要一个块,返回必须是明确的


11

这里还有另一种情况。

在React中编写功能组件时,可以使用括号来包装隐式返回的JSX。

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

4
您总是可以使用括号,它 JSX或React 无关
Emile Bergeron,

3

箭头函数使您可以隐式返回:无需使用return关键字即可返回值。

当函数体中存在在线语句时,它可以工作:

const myFunction = () => 'test'

console.log(myFunction()) //'test'

另一个示例,返回一个对象(记住将花括号括在括号中,以避免将其视为包裹函数的主体括号):

const myFunction = () => ({value: 'test'})

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


1
尽管需要更多说明,这应该是正确的答案。基本上,当函数主体是表达式而不是块时,该表达式的值将隐式返回。如我错了请纠正我。
Paul-Sebastian Manole

3

这是另一个给我带来麻烦的情况。

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

在这里,我们定义了一个返回匿名函数的函数。“棘手的”位是外部函数的函数主体(以(bar)=> ...开头的部分)在视觉上看起来像“块”,但事实并非如此。由于不是,所以隐式返回开始。

换行的执行方式如下:

// 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'));

我对此进行解包以确保我理解它的方法是“使这些函数“不趋于缩小”。

这是第一个代码块的语义等效项,只是使wrap()的主体进行显式返回。该定义产生与上述相同的结果。这是点连接的地方。将上面的第一个代码块与下面的代码块进行比较,很明显,箭头函数本身被视为一个表达式,而不是一个块,并且具有隐含的return

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

Wrap的完全未缩小版本将是这样的,虽然它不像粗箭头所示的版本那么紧凑,但似乎很容易理解。

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

最后,对于其他可能不得不阅读我的代码以及将来我的代码的人,我认为我更喜欢使用非箭头版本,该版本乍一看就可以在视觉上理解,而不是箭头版本,它花了很多时间。以为(在我的情况下是实验)发呆。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.