Скільки я повинен використовувати "Let" vs "const" в ES6?


214

Нещодавно я писав багато кодів ES6 для io.js. У дикій природі не так багато коду, чому можна навчитися, тому я відчуваю, що я визначаю свої власні умовності, коли я йду.

Моє питання про те, коли використовувати constпроти let.

Я застосовував це правило: Якщо можливо, використовуйте const. Використовуйте лише letякщо ви знаєте, що його значення потрібно змінити. (Ви завжди можете повернутися назад і змінити constзначення a, letякщо пізніше виявиться, що вам потрібно змінити його значення.)

Основна причина цього правила - це легко застосовувати послідовно. Сірих ділянок немає.

Справа в тому, що коли я застосовую це правило, на практиці 95% моїх декларацій є const. І це мені дивно виглядає. Я використовую лише letдля таких речей, як iу forциклі, або іноді для таких речей, як накопичені підсумки Фібоначчі (що в реальному житті не дуже багато). Мене це здивувало - виявляється, 95% 'змінних' у моєму коді ES5 на сьогодні були для значень, які не змінюються. Але бачити constвесь мій код почувається якось неправильно.

Отже, моє запитання: чи нормально constтак багато використовувати? Чи справді я повинен робити такі речі const foo = function () {...};?

Або я повинен зарезервувати constтакі ситуації, коли ти чітко кодуєш літерал у верхній частині модуля - такий, як ти робиш з великими літерами, як const MARGIN_WIDTH = 410;?


7
Я підозрюю, що це питання в першу чергу ґрунтується на думці і, таким чином, ймовірно, буде закритим, але мої 2 копійки: Це нормально використовувати constце багато.
Джомінал

15
function foo() {...}краще, ніж<anything> foo = function() {...}
OrangeDog

12
@OrangeDog Я хотів би бачити ваше пояснення з цього приводу, оскільки я зробив висновок прямо протилежне. Існує застереження, яке function foo() {...}може викликати незначну плутанину при налагодженні через підйом. Також його існування означає, що у нас є дві конструкції, які роблять те саме, але одна з них працює лише у дуже специфічному контексті. (Ви можете використовувати вираз функції будь-де, де може існувати вираз, але ви можете використовувати декларацію функції лише на рівні заяви.) Якщо ви віддаєте перевагу стислості, проблема може полягати лише в тому, що в синтаксисі виразу функції використовується все слово function.
Кін

11
Сліди стеків мають назву функції замість anon. Підйом хороший, і давайте визначимо функції в природному порядку, не турбуючись про те, що foo не буде визначено.
OrangeDog

1
Це хороші моменти, які слід пам’ятати, але я ще не переконаний. Сучасні відладчики роблять добру роботу, вибираючи правильне відображуване ім’я для вашої функції, виходячи з того, якому символу ви присвоїли його (якщо такий є - якщо його немає, ви можете використовувати виражений функцію з назвою). Природний порядок оголошення функції є високо суб'єктивним. Може бути розумним думати, що природний порядок починається з визначення основних частин, а потім пізніше визначення частин, які їх використовують.
Кін

Відповіді:


183

Моя відповідь тут не стосується JavaScript.

Як правило, на будь-якій мові, яка дозволяє мені це робити напівпростим способом, я б сказав, що завжди використовуйте const / final / readonly / все, що воно називається вашою мовою, коли це можливо. Причина проста, набагато простіше міркувати про код, коли він мертвий, очевидно, що може змінитися, а що не може змінитися. На додаток до цього, на багатьох мовах ви можете отримати підтримку інструментів, яка говорить про те, що ви робите щось не так, коли ви присвоюєте особі змінну, яку ви оголосили як const.

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

Скільки помилок ви бачили, що зміни змін несподівано змінювались? Я б багато здогадався. Я знаю, що більшість помилок, які я бачу, пов'язані з несподіваними змінами стану. Ви не позбудетесь від усіх цих помилок, використовуючи const, але ви позбудетеся від багатьох!

Крім того, у багатьох функціональних мовах є незмінні змінні, де всі змінні за замовчуванням const. Подивіться, наприклад, Erlang або F #. Кодування без призначення прекрасно працює на цих мовах і є однією з багатьох причин, чому люди люблять функціональне програмування. З цих мов можна багато чому навчитися керувати державою, щоб стати кращим програмістом.

І все починається з надзвичайно ліберальної з const! ;) Лише ще два символи написати в порівнянні з дозволеними, тому продовжуйте і constвсе!


45
const- це ще два символи, ніж let...
OrangeDog

72
Але на 5 символів менше, ніж незмінне.
Серад

7
Це схоже на те, як використовувати valв Scala (який оголошує змінну незмінною) і використовувати лише var(змінний еквівалент), коли ми не можемо використовувати val. Іншими словами, ми оголошуємо змінні як незмінні за замовчуванням і вводимо мутабельність лише тоді, коли вона нам абсолютно потрібна (що може бути просто тому, що мутаційний підхід чистіший).
Кет

7
Я погоджуюся з цією відповіддю, але майте на увазі, що при роботі з такими предметами, як звичайні об'єкти чи масиви, не так очевидно, що їхні властивості можуть змінюватися, навіть якщо вони були визначені "const". Я думав про «const», що працює як object.freeze, але це не так.
бекдек

2
@Cerad Ви мали на увазі "на 4 символи менше" чи я тут пропускаю жарт?
Mathias Bynens

57

Будьте обережні, тому що constклавіші об'єкта є змінними.

Звідси: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

об'єктні клавіші не захищені

розглянемо цей приклад:

const colors = {red: "#f00"}; 
console.log(colors); // { "red": "#f00" }

colors.red = "#00f";
colors.green = "#0f0";
console.log(colors); // { "red": "#00f", "green": "#0f0" }

Те ж саме для масивів:

const numbers = [1, 2, 3];
console.log(numbers); // [ 1, 2, 3 ]

numbers.push(4);
console.log(numbers); // [ 1, 2, 3, 4 ]

Я не вирішив себе повністю, але я розглядаю можливість використання constдля всіх не масивів / не-об'єктів і використання letдля об'єктів / масивів.


34
Щоправда, але очікуваний IMO - постійне посилання на об'єкт, присвоєне вашому const. colors = numbersне буде працювати, як очікувалося. Якщо ви хочете захистити свої об'єкти, ви можете скористатися Object.freeze() developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Йозеф Енгельфрост

16
Оманливий оман. Це непорушне. Але фактичних властивостей об'єкта немає.
Гастон Санчес

1
+1 Так, посилання захищене, але з точки зору питання , це досить нерозумно використовувати у таких випадках const moment = require('moment'), якщо ви не тип людини, який переживає, що хтось спробує зробити це moment = dead.fish(() => pizza)пізніше.
MaxWell

5
Можливо, реалістичніше хвилюватися moment = Date.now(). Але в будь-якому випадку, якщо код вважає інваріантом, я не бачу нічого поганого в тому, щоб його застосувати, де це можливо.
Джеймс М.

3
Ніхто не сказав, що вони не були непорушними. Поширене непорозуміння, що мета const - зробити його непорушним, коли це дійсно гарантувати, що ім’я ніколи не посилається на інший об'єкт, ніж той, для якого він був ініціалізований.
монокром

25

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

Що стосується об'єктів, constзахистить вашу змінну від перепризначення, але якщо вам потрібні незмінні об'єкти, вам знадобиться Object.freezeметод, див. Нижче.

const immutableOject = Object.freeze({immutableProperty: 'foo'});

constзахистить лише від перепризначення, а freezeметод захистить усі негайні властивості. Якщо вам також потрібні всі вкладені властивості, щоб вони були незмінні, тоді вам потрібно буде freezeїх рекурсивно .


14
Зверніть увагу, що Object.freezeце неглибоко.
Mathias Bynens

@MathiasBynens Я натрапив на цей коментар і мені цікаво, що саме ти мав на увазі під цим. Чи можете ви, будь ласка, докладно?
Коул Робертс

@ColeRoberts Поняття неглибокої незмінності - це коли посилання на об'єкт сама по собі незмінна, але властивості все одно можна змінити. Ключове слово const створює лише дрібну незмінність, отже, вам потрібно використовувати Object.freeze, якщо всі властивості також повинні бути незмінні.
clean_coding

3
@ColeRoberts Це означає, що значення об'єкта в замороженому об'єкті (тобто вкладені об'єкти) все ще можна мутувати. Для отримання додаткової інформації див. Mathiasbynens.be/notes/es6-const#immutable-values .
Mathias Bynens

19

У моєму ES6 constне йдеться про пост незмінності , я пояснюю, що constсаме означає відповідно до специфікації.

Виходячи з цих об'єктивних фактів, ось мої особисті переваги:

[…] В коді ES6 має сенс використовувати letта constнаступне:

  • використовувати constза замовчуванням
  • використовувати лише в letразі необхідності повторного перезавантаження (тобто будь-якої форми переназначення)
  • ( varне слід використовувати в ES6)

Як це суб'єктивно, це факт, що це найбільше відповідає наміру специфікації.

Люди, які використовують letза замовчуванням, зазвичай трактують constзмінні як константи (що це не обов'язково за дизайном!). Кожен свій, але я вважаю за краще використовувати речі за призначенням, а не для певного складеного сенсу, який люди присвоюють йому на основі непорозуміння.

Використовувати constлише для констант - це як використовувати елемент HTML<aside> лише для вмісту бічної панелі.


2
Навіщо ти щось називати, constякщо воно не є постійним?
nu everest

3
@nueverest Тому що це не для чого const. Ви читали вище?
Mathias Bynens

2
@MathiasBynens Я думаю, що (єдиною?) Проблемою constє те, що вона називається const. Це німе ім’я (у JavaScript), яке спочатку бентежить багатьох (усіх?) Розробників. ІМО краще було б, якби constйого викликали let(тим більше, що letвін коротший, але constнабагато частіше) і letназивав би щось інше.
MrN00b

@MathiasBynens я розумію, але навіщо це називати? Це створює величезну кількість плутанини, як це демонструє ця сторінка.
jtr13

4

Мій особистий підхід, продуманий для сприяння читанні та розумінню коду:


letє лише для короткочасних змінних, визначених в одному рядку і не змінених після. Взагалі ті змінні, які існують лише для зменшення кількості введення тексту. Наприклад:

for (let key in something) {
  /* we could use `something[key]` for this entire block,
     but it would be too much letters and not good for the
     fingers or the eyes, so we use a radically temporary variable
  */
  let value = something[key]
  ...
}

constдля всіх імен, які, як відомо, є постійними для всього модуля Не враховуючи локально постійних значень. Наприклад, valueу наведеному вище прикладі є постійним у своєму обсязі і його можна оголосити за допомогою const, але оскільки існує багато ітерацій, і для кожного є значення з тим самим ім'ям , "value", що може наштовхнути читача на думку valueзавжди той самий. Модулі та функції - найкращий приклад constзмінних:

const PouchDB = require('pouchdb')
const instantiateDB = function () {}
const codes = {
  23: 'atc',
  43: 'qwx',
  77: 'oxi'
}

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

var output = '\n'
lines.forEach(line => {
  output += '  '
  output += line.trim()
  output += '\n'
})
output += '\n---'

for (let parent in parents) {
  var definitions = {}
  definitions.name = getName(parent)
  definitions.config = {}
  definitions.parent = parent
}

Подальші коментарі та можливі майбутні оновлення тут .


10
цей другий фрагмент коду схожий на пістолет.
Джуліан

1

JavaScript трохи особливий тим, що змінні можуть бути функціями і такими, але врахуйте в C #, Java або іншій подібній мові стилю C:

const public void DoSomething()

Це constне дивно, і це тому, що декларації методів на цих мовах не можуть змінитися, як тільки вони складені в щось інше, це те, що вони роблять, незважаючи ні на що (ігноруючи деякі жахливі хаки, які можуть існувати).

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

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