【问题标题】:When should I use a return statement in ES6 arrow functions什么时候应该在 ES6 箭头函数中使用 return 语句
【发布时间】:2022-01-19 11:15:12
【问题描述】:

新的ES6 arrow functionsreturn 在某些情况下是隐含的:

表达式也是该函数的隐式返回值。

在什么情况下我需要将return 与 ES6 箭头函数一起使用?

【问题讨论】:

    标签: javascript ecmascript-6 arrow-functions


    【解决方案1】:

    Jackson 在类似的问题中有部分answered this

    隐式返回,但前提是没有阻塞。

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

    我会在此添加block 的定义:

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

    示例

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

    【讨论】:

    • 我不明白那个语法..你是在使用类 littoral 创建一个类,然后用一个参数('Jess')调用一个隐含的构造函数吗?我以为你会这样做 ((name) => ({id: 'Jess'}))
    • @MichaelDausmann 这是一个箭头函数,它有一个参数name,该函数用括号括起来并用一个参数“Jess”调用。在每种情况下,=>)('Jess') 之间的代码都是箭头函数的主体。将其视为 (function (name) { return { id: name } })('Jess') 形式的立即调用函数表达式的缩写形式
    • 非常有用!有助于发现 Promises.all 中使用箭头函数映射项目的问题,如果使用箭头函数映射数组没有返回值,您会注意到是否得到未定义的数组。
    • 对箭头函数进行系统化隐式返回会有什么缺点?就像coffeescript 一样......(虽然我不喜欢coffeescript)
    • 要清楚,似乎是因为 JS 解析器不知道是期望一个 表达式(例如包含对象字面量 {} 的表达式)还是block,它假定{ } 表示一个块。这意味着当它看到id: name 时,它认为id: 是一个创建label 的表达式(处理流控制并使用: 的JS 非常不常用的功能),然后是@987654339 @ 跟随id: 只是一个单独的语句,它只包含变量name(& 什么都不做)。
    【解决方案2】:

    我理解这个经验法则......

    对于有效转换的函数(参数的单行操作),return 是隐式的。

    候选人是:

    // square-root 
    value => Math.sqrt(value)
    
    // sum
    (a,b) => a+b
    

    对于其他操作(需要块的多行,return 必须是显式的

    【讨论】:

      【解决方案3】:

      这里还有一个案例。

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

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

      【讨论】:

      • 你总是可以使用括号,它与 JSX 或 React 无关
      【解决方案4】:

      这是另一个给我带来麻烦的案例。

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

      这里我们定义了一个返回匿名函数的函数。“棘手”的一点是外部函数的函数体(以 (bar) => ... 开头的部分)在视觉上看起来像一个“块”,但是它不是。既然不是,隐式返回就开始了。

      以下是 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'));
      

      我解包以确保我理解它的方式是“取消”功能。

      这是第一个代码块的语义等价物,只是让 wrap() 的主体进行显式返回。此定义产生与上述相同的结果。这是点连接的地方。比较上面的第一个代码块和下面的代码块,很明显箭头函数本身被视为an expression, not a block, and has the implied 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;
        };
      };
      

      最后,对于可能需要阅读我的代码的其他人,以及未来的我,我想我更愿意去使用第一眼就可以理解的非箭头版本,而不是需要一个相当多的想法(在我的案例中是实验)去探索。

      【讨论】:

      • 很好的解释!谢谢。
      • 很好的解释。你能表达一下它调用的方法/过程吗?
      • 基本上是这样吧? const wrap = function(foo) { return function(bar) { if (foo === 'foo') return foo + ' ' + bar;返回 '​​nofoo' + 酒吧; }; }; //运行包装函数:wrap('foo')('bar');
      【解决方案5】:

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

      当函数体中有在线语句时有效:

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

      另一个例子,返回一个对象(记得将花括号括在括号中,以免它被认为是包装函数体括号):

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

      【讨论】:

      • 这应该是正确的答案,尽管需要更多解释。基本上,当函数体是一个表达式而不是一个块时,该表达式的值将被隐式返回。如果我错了,请纠正我。
      【解决方案6】:

      在以下情况下,可以忽略箭头函数中的括号 {} 和 return 关键字: (1) 在 return 语句之前你不会有任何代码(例如赋值语句)和 (2) 您将返回单个实体 [注意:单个实体可以是多行。如果是这样,那么您所需要的只是常规括号(),如下例所示:

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

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多