Зачем использовать `const foo = () => {}` вместо `function foo () {}`

12

Например, в этом видео Redux инструктор всегда использует такой синтаксис, как

const counter = (state=0, action) => {
   ... function body here
}

где я бы просто использовал «традиционный»

function counter(state=0, action) {
   ... function body here
}

Что на самом деле короче и, ИМО, понятнее. Проще отсканировать достаточно ровный и структурированный левый край страницы на наличие слова «функция», чем отсканировать рваный правый край на предмет небольшого «=>».

Кроме того this, пытаясь быть объективным, а не мнением, есть ли какое-то полезное отличие или преимущество в новомодном синтаксисе?

user949300
источник
3
Этот вопрос о StackOverflow может вас заинтересовать: stackoverflow.com/questions/34361379/…
Винсент Савард,
3
Я не эксперт по JavaScript, но, думаю, constпомогает гарантировать, что функция не будет переопределена позже.
MetaFight
Спасибо @VincentSavard, это прекрасно, и в основном то, что я ожидал: кроме «this» и прототипов / классов, похоже, нет никакой разницы.
user949300
3
@ user949300 Там является разница, то один MetaFight упоминает. Кроме того, прототип / «этот материал» также быстро становится критическим отличием.
мсанфорд
1
Короче говоря: вы должны ценить ясность и лаконичность, а не преимущества.
Уэйн Блосс

Ответы:

11

Операторы функций (именованные функции, показанный 2-й синтаксис) поднимаются до вершины полной лексической области, даже за произвольными и управляющими блоками, как ifоператоры. Использование const(например let) для объявления переменной дает ей область видимости блока, останавливает полное поднятие (поднятие до простого блока) и гарантирует, что она не может быть повторно объявлена.

При объединении сценариев вместе или в некоторых, использующих другие инструменты создания пакетов, подъем функций может нарушать конфликтующие сценарии способами, которые трудно отладить, так как они молча завершаются неудачей. Повторно объявленный constвызовет исключение, прежде чем программа сможет работать, так что отладка будет намного проще.

dandavis
источник
Спасибо. хороший ответ В основном я работал над небольшими JS-проектами или серверными проектами node.js, где у них есть хорошая модульная система для пространств имен. Но просто начните с более клиентского проекта с использованием упаковщиков, и это хорошая идея.
user949300
2
Просто обратите внимание, что eslint no-func-assign может уловить эту проблему переопределения.
user949300
2
Написание кода, содержащего непонятные сигналы для получения преимуществ статически типизированного языка, является причиной использования Typescript, а не так const. IMO, это немного недальновидно, чтобы начать использовать его constповсюду по этой причине в возрасте eslint, webpack, babel и так далее. Никто больше не объединяет файлы вручную, по крайней мере, уже десять лет.
Уэйн Блосс
2

Вот почему вы должны использовать function:

  1. Сигнализация четкая и лаконичная. Это гораздо более выгодно, чем любая из проблем подъема краевого случая, которые перечислены в другом ответе.

  2. Вы действительно хотите подняться внутри модулей, потому что, как вы можете видеть из приведенного ниже кода, constобъявление tryDoTheThingсбой молча и не будет перехвачено, пока вы не попытаетесь вызвать его.

  3. Большинство юниоров, с которыми я сталкиваюсь, начинают использовать constдля объявления каждой функции, потому что это прихоть прямо сейчас, например, использовать пробелы над вкладками или делать все, functional!!!потому что «ООП плох». Не делай этого. Вы не хотите быть тем парнем, который следует за причудами, не понимая полностью их значения.

через https://gist.github.com/stephenjfox/fec4c72c7f6ae254f31407295dc72074


/*
This shows that, because of block-scoping, const function references must be
invoked in-order or else things will fail silently.
const's are added the name space serially (in the order in which they appear)
and much of the body isn't declared when we first try to invoke or functions
*/


const tryDoTheThing = () => {
  console.log(`This is me trying to be awesome ${getAwesome()}`)
}


// "getAwesome is not defined", because it is referenced too early
tryDoTheThing() // comment to see the rest work


const getAwesome = () => (+((Math.random() * 10000).toString().split('.')[0]))


const doTheThing = () => {
  console.log(`This is awesome! ${getAwesome()}`)
}

doTheThing() // prints

против

/*
Function declarations are given two passes, where the first lifts them to
the top of the namespace, allowing "out of order" usage
*/

doTheThing();


function doTheThing() {
  console.log(`This is awesome number ${getAwesome()}`)
}

function getAwesome() {
  return (+((Math.random() * 10000).toString().split('.')[0]))
}
Уэйн Блосс
источник