Коли я повинен використовувати `return` у функціях стрілки es6?


154

Нові функції стрілок es6 кажуть return, що при деяких обставинах неявна:

Вираз є також неявним зворотним значенням цієї функції.

У яких випадках мені потрібно користуватися returnфункціями стрілок es6?

Відповіді:


262

Джексон частково відповів на це аналогічним запитанням:

Неявне повернення, але тільки якщо блоку немає.

  • Це призведе до помилок, коли однолінійка розшириться на кілька рядків, і програміст забуде додати 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") ?? Я думав, що ви до цього ((ім'я) => ({id: 'Jess'}))
Майкл Даусман

3
@MichaelDausmann Це функція зі стрілкою, яка має один параметр, nameіз функцією, укладеною в круглі дужки та викликається одним аргументом "Jess". Код між =>і )('Jess')в кожному випадку є тілом функції стрілки. Розглянемо це як коротку форму функції негайно викликаної форми Вираз форми(function (name) { return { id: name } })('Jess')
Russ Cam

Дуже корисно додано! допомагає виявити проблеми в Promises.all, які відображають об’єкти з функцією стрілки, і ви можете помітити, якщо ви отримаєте масив невизначених, якщо для відображення масиву з функціями стрілки не було повернено значення.
Джей шах

Який був би мінус зробити неявне повернення систематичним для функцій стрілок? Так само, як це робить coffeescript ... (хоча мені не подобається coffeescript)
Августин Рідінгер

4
Щоб було зрозуміло, здається, що оскільки JS-аналізатор не знає, чи слід очікувати виразу (наприклад, виразу, що містить об'єкт-буквал {}) чи блоку , він передбачає, що { }позначає блок. Це означає , що , коли він бачить id: name, що думає , id:цей вислів створює ярлик (дуже незвично, використовувану функцію JS , яка має справу з керуванням потоком і використовує :), а потім в nameнаступному id:це просто окреме заяві , яке містить тільки змінну name(& нічого не робить).
іоно

18

Я розумію це правило роботи ...

Для функцій, які ефективно перетворюються (однорядкові маніпуляції аргументами), повернення є неявним.

Кандидатами є:

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

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

Для інших операцій (більше одного вкладиша, для якого потрібен блок, повернення має бути явним


11

Тут є ще один випадок.

Записуючи функціональний компонент в React, ви можете використовувати дужки, щоб обернути неявно повернений JSX.

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

4
Ви завжди можете використовувати дужки, це не пов'язано з JSX або React.
Еміль Бержерон

4

Ось ще один випадок, який доставив мені певну проблему.

// 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 () зробити явне повернення. Це визначення дає ті самі результати, що і вище. Тут з’єднуються точки. Порівняйте перший блок коду вище із наведеним нижче, і зрозуміло, що сама функція стрілки трактується як вираз, а не як блок, і мається на увазі повернення .

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

Повністю нерафіфікована версія обгортки виглядає так, що, хоча і не така компактна, як жирова стрілка версії, здається набагато простішою для розуміння.

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

Зрештою, для інших, яким, можливо, доведеться читати мій код, і майбутніх мені, я вважаю, що я вважаю за краще скористатися не стрілковою версією, яку можна зрозуміти візуально на перший погляд, а не стрілкою, яка займає неабияку частину подумав (і в моєму випадку експериментував), щоб грозити.


3

Функції стрілки дозволяють мати неявне повернення: значення повертаються без використання returnключового слова.

Він працює, коли в тілі функції є он-лайн оператор:

const myFunction = () => 'test'

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

Ще один приклад повернення об'єкта (не забудьте загортати фігурні дужки в дужки, щоб уникнути його врахування дужок корпусу функції обтікання):

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

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


1
Це має бути правильна відповідь, хоча вона потребує трохи більше пояснень. В основному, коли тіло функції - це вираз, а не блок, значення цього виразу повертається неявно. Виправте мене, якщо я помиляюся.
Пол-Себастьян Маноле
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.