Належне використання const для визначення функцій у JavaScript


183

Мене цікавить, чи є обмеження щодо того, які типи значень можна встановити за допомогою constJavaScript - зокрема функцій. Чи дійсно це? Звичайно, це працює, але чи вважається це поганою практикою з будь-якої причини?

const doSomething = () => {
   ...
}

Чи слід усі функції визначати таким чином у ES6? Здається, це не наздогнало, якщо так.

Дякуємо за будь-які коментарі!


Ви, здається, задаєте кілька запитань: 1) "Мене цікавить, чи існують обмеження щодо того, які типи значень можна встановити, використовуючи const в JavaScript" № 2) "Це дійсно?" Так. 3) "Чи вважається це поганою практикою з будь-якої причини", я думаю, її не було досить довго, щоб щось про це сказати, але я не розумію, чому це повинно бути практикою накладки. Це не сильно відрізняється від var doSomething = <function def>;. 4) "Чи повинні усі функції визначені таким чином у ES6?" Мені здається громіздким. Мені подобаються декларації функцій. У кожного свої.
Фелікс Клінг

1
Те, як я це бачу (думка, а не факт), має сенс, якщо ви хочете заборонити перевизначення функцій. Незалежно від того, чи це розумне, чи функціональне використання - це дискусійно. Якщо ви вважаєте, що це відповідає вашому сценарію використання, я не думаю, що хтось може аргументувати ваше рішення і вважати це поганою практикою.
Mjh

4
Я думаю, питання полягає в тому, чого ви хочете досягти const. Ви хочете не допустити перекриття функції? Я припускаю, що ви знаєте свій код, щоб цього не робити. Ви хочете висловити наміри doSomething, тобто, що він виконує функцію і не змінює свого значення? Я думаю, що декларації функцій також чітко передають цей намір. Тож, якщо вам потрібен "захист від виконання" від перевищення, перейдіть до цього. Інакше я не бачу великої користі. Звичайно, якщо ви в першу чергу використовували var foo = function() {};, я б використовував constзамість цього var.
Фелікс Клінг

5
@FelixKling, "Я припускаю, що ви знаєте свій код, щоб цього не робити". - це досить поганий аргумент. Інакше взагалі немає сенсу const.
meandre

Відповіді:


254

Немає проблем з тим, що ви зробили, але ви повинні пам’ятати про різницю між оголошеннями функції та виразами функцій.

Декларація функції, тобто:

function doSomething () {}

Піднімається повністю на верхню частину області (і подобається, letі constвони також блокуються).

Це означає, що працює наступне:

doSomething() // works!
function doSomething() {}

Вираз функції, тобто:

[const | let | var] = function () {} (or () =>

Це створення анонімної функції ( function () {}) та створення змінної, а потім присвоєння цієї анонімної функції цій змінній.

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

Це означає:

if (true) {
    doSomething() // will fail
    const doSomething = function () {}
}

Вийде з ладу, оскільки doSomethingне визначено. (Це кине а ReferenceError)

Якщо ви перейдете на використання, varви отримаєте підняття змінної, але вона буде ініціалізована до undefinedтого, що блок коду вище все ще не буде працювати. (Це буде кидати, TypeErrorоскільки doSomethingце не є функцією в той момент, коли ви його називаєте)

Що стосується стандартних практик, ви завжди повинні використовувати належний інструмент для роботи.

Axel Rauschmayer має чудову посаду щодо сфери застосування та підйому, включаючи семантику es6: Змінні та сфера застосування в ES6


7
Хочеться лише додати, що класи es6 використовують const внутрішньо для захисту назви класу від переназначення в межах класу.
user2342460

2
Одна тонка різниця між a function a(){console.log(this);} і b const a=_=>{console.log(this);} полягає в тому, що якщо ви називаєте це так a.call(someVar);, в a , воно друкується someVar, в b воно друкується window.
Qian Chen

100

Хоча використання constдля визначення функцій виглядає як хак, але це має деякі великі переваги, які роблять його вищим (на мій погляд)

  1. Це робить функцію незмінною, тому вам не потрібно турбуватися про те, що цю функцію змінить якийсь інший фрагмент коду.

  2. Ви можете використовувати синтаксис жирної стрілки, який коротший і чистіший.

  3. Використання стрілочних функцій забезпечує thisподбання для вас.

приклад з function

// define a function
function add(x, y) { return x + y; }

// use it
console.log(add(1, 2)); // 3

// oops, someone mutated your function
add = function (x, y) { return x - y; };

// now this is not what you expected
console.log(add(1, 2)); // -1

той же приклад із const

// define a function (wow! that is 8 chars shorter)
const add = (x, y) => x + y;

// use it
console.log(add(1, 2)); // 3

// someone tries to mutate the function
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable.
// the intruder fails and your function remains unchanged


1
І ви можете двічі оголосити функцію add (x, y), але ви не можете оголосити двічі const add = ...
TatianaP

33
1. Незмінюваність - це справжня користь, але дуже рідко хтось переписує функцію. 2. Синтаксис жирної стрілки не коротший, якщо ваша функція не може бути виразом. function f(x, y) {є 18 символів, const f = (x, y) => {це 21 символ, тому на 3 символи довше. 3. Збереження цього прив'язки має значення лише в тому випадку, якщо функції визначені всередині методу (або іншої функції, яка має сенс цього). На сценарії верхнього рівня це безглуздо. Я не кажу, що ви помиляєтесь, лише те, що ви згадуєте причини, не дуже актуальні.
Голий

@Nakedible тож які ще є вагомі причини?
Аніш Рамасвамі

13
Однією з переваг синтаксису старомодної функції є те, що під час налагодження він має назву.
user949300

3
Я б використовував вкладиші для запобігання повторного прив'язки декларації функції.
Франклін Ю.

32

Минуло три роки, як це питання було задано, але я зараз лише стикаюся з ним. Оскільки ця відповідь знаходиться так далеко внизу стеку, дозвольте мені повторити її:

З: Мене цікавить, чи існують обмеження щодо того, які типи значень можна встановити, використовуючи const в JavaScript - зокрема функції. Чи дійсно це? Звичайно, це працює, але чи вважається це поганою практикою з будь-якої причини?

Мене мотивували зробити деякі дослідження після того, як я спостерігав за одним плідним кодером JavaScript, який завжди використовує constзаяву для functions, навіть коли немає явної причини / вигоди.

У відповідь на те, " чи вважається це поганою практикою з будь-яких причин? ", Дозвольте сказати, IMO, так, це, або, принаймні, є переваги використання functionоператора.

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

Постійне плутанина: чому я все ще використовую оператори JavaScript функціями medium.freecodecamp.org/Bill Sourour, гуру JavaScript, консультант та викладач.

Я закликаю всіх прочитати цю статтю, навіть якщо ви вже прийняли рішення.

Ось основні моменти:

Оператори функцій мають дві явні переваги перед [const] функціями:

Перевага №1: Ясність наміру

Переглядаючи тисячі рядків коду на день, корисно мати можливість з'ясувати наміри програміста якомога швидше і простіше.

Перевага №2: Порядок декларування == порядок виконання

В ідеалі я хочу оголосити свій код більш-менш у тому порядку, на який я очікую, що він буде виконаний.

Це для мене showstopper: будь-яке значення, оголошене за допомогою ключового слова const, недоступне, поки виконання не досягне його.

Те, що я нещодавно описав вище, змушує нас писати код, який виглядає догори дном. Ми повинні почати з функції найнижчого рівня і просуватися вгору.

Мій мозок не працює так. Я хочу контекст перед деталями.

Більшість кодів написані людьми. Тож має сенс, що порядок розуміння більшості людей приблизно відповідає порядку виконання більшості кодів.


1
Чи можете ви прокоментувати трохи більше ясності намірів? Я отримую №2, але, наскільки я можу сказати, №1 - це лише (перед?) Повторення №2. Я можу придумати випадок, тобто функції, які мають власну defaultErrorHandlerconst, призначену як анонімну функцію, яку я потім можу викликати від обробників обіцянок. Це дасть мені змогу необов'язково "переосмислити" цей обробник помилок за замовчуванням у межах функцій, як мені потрібно. Деяким потрібно лише повернути об’єкт помилки, а іншим потрібно повернути http-відповідь, різного рівня багатослівності. Однак структура коду може бути звичною схемою незалежно.
Джейк Т.

Можливо, моя ідея занадто згорнута! Тільки обернувшись головою навколо деяких нових практик, я ще не витратив багато часу на їх реалізацію. Щойно я знаходжу, що мені справді подобається .then( res.success, res.error )набагато більше, ніж анонімні функції, які я оголосив просто зателефонувати res.success(value);. Наявність .then( ..., defaultErrorHandler)загального шаблону може бути непоганим, з вищим рівнем, визначеним за замовчуванням функцієюErrorHandler, і, за бажанням, const defaultErrorHandler = error => { ... }задекларовано у межах функції, як бажано.
Джейк Т.

1
@JakeT. RE "Чи можете ви прокоментувати трохи більше ясності наміру?". Ну, по-перше, це твердження було зроблено не моїм мною, а автором freecodecamp.org/Bill Sourour, автором цієї статті. Але це має для мене справжній здоровий глузд. Якщо я прочитаю "функція завтра ()", я одразу знаю, що це функція. Але якщо я прочитаю "const завтра = () =>", я зупиняюся на мить і розбираю синтаксис в голові, щоб остаточно визначити, гаразд, так, це функція.
JMichaelTX

1
Інша справа, якщо у мене є довгий сценарій, написаний кимось іншим, і я хочу побачити всі функції, я можу швидко здійснити пошук "функції", щоб знайти їх. Або ще краще, я можу написати швидкий JS RegEx, щоб витягти всі функції. IMO, твердження "const" - це лише дані (а не функції), які НЕ змінюватимуться.
JMichaelTX

10

Існує кілька дуже важливих переваг від використання, constа деякі кажуть, що його слід використовувати, коли це можливо, через те, наскільки це навмисно та орієнтовно.

Наскільки я можу сказати, це найбільш показове і передбачуване декларування змінних у JavaScript, і одне з найкорисніших, ЗАСЛІДЖЕНО наскільки воно обмежене. Чому? Тому що це виключає деякі доступні можливості varтаlet декларації.

Що ви можете зробити, коли читаєте const? Ви знаєте все наступне, просто прочитавши constзаяву декларації І без пошуку інших посилань на цю змінну:

  • значення пов'язане з цією змінною (хоча її основний об'єкт не є глибоко незмінним)
  • до нього не можна отримати доступ за межами свого безпосередньо блоку
  • Прив'язка ніколи не доступна перед оголошенням через правила тимчасової мертвої зони (TDZ).

Наступна цитата - зі статті, що аргументує переваги letта const. Він також безпосередньо відповідає на ваше запитання щодо обмежень / обмежень ключового слова:

Такі обмеження, як ті, які пропонує letі constє потужним способом полегшити розуміння коду. Спробуйте накопичити якомога більше цих обмежень у написаному вами коді. Чим більше декларативних обмежень, які обмежують, що може означати фрагмент коду, тим легше і швидше людині читати, аналізувати та розуміти фрагмент коду в майбутньому.

Звичайно, існує більше правил для constдекларації, ніж varдекларації: блок-діапазон, TDZ, присвоєння при декларації, переназначення немає. Враховуючи те, що varоператори визначають лише визначення функції сигналу Однак підрахунок правил не пропонує багато розуміння. Краще зважити ці правила за складністю: додає правило чи віднімає складність? У випадкуconst , коли масштабування блоків означає більш вузький обсяг, ніж масштабування функції, TDZ означає, що нам не потрібно сканувати область застосування від декларації, щоб помітити використання перед оголошенням, а правила присвоєння означають, що прив'язка завжди буде зберігати така ж довідка.

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

Маючи на увазі ці аргументи, рекомендується використовувати constтам, де це можливо, оскільки саме це твердження дає нам найменші можливості подумати.

Джерело: https://ponyfoo.com/articles/var-let-const

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