Коли я повинен використовувати `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.