ES6 const це не про иммутабельность

Визначення const вводить в оману, яке повинно бути розвіяне:

const створює иммутабельную посилання на об'єкт, але це не означає, що не можна буде змінити — ні, це значення може бути змінено. Наступний код не буде помилкою:

const foo = {};
foo.bar = 42;
console.log(foo.bar);
// → 42

const arr = [0, 20, 30];
arr[0] = 10;
console.log(arr);
// → [10, 20, 30]

Єдина річ, яка тут незмінна, це посилання на об'єкт. const присвоює значення ( { } ) до змінної foo, і гарантує, що присвоєння нового не буде. Використання оператора присвоєння, а також унарных або постфиксных операторів — і ++ викличе помилку TypeError.

const foo = 27;
// Всі операції нижче викличуть помилку
// Оператори присвоєння:
foo = 42;
foo *= 42;
foo /= 42;
foo %= 42;
foo += 42;
foo -= 42;
foo <<= 0b101010;
foo >>= 0b101010;
foo >>>= 0b101010;
foo &= 0b101010;
foo ^= 0b101010;
foo |= 0b101010;
// Унарні `--` і `++`:
--foo;
++foo;
// Постфиксные `--` і `++`:
foo--;
foo++;

ES6 const нічого не робить з неизменяемостью даних.

Так як же тоді отримати иммутабельное значення?
Примітивні типи даних, такі як numbers, strings, booleans, symbols, null, or undefined завжди иммутабельны.

var foo = 27;
foo.bar = 42;
console.log(foo.bar);
// → `undefined`

Для того, щоб зробити дані иммутабельными, використовуйте Object.freeze(). Цей метод доступний з часів ES5.

const foo = Object.freeze({
'bar': 27
});
foo.bar = 42; // TypeError exception за умови використання strict mode;
console.log(foo.bar);
// → 27

Але пам'ятайте, що Object.freeze() поверхневий, тобто у замороженого об'єкта досі залишиться можливість змінювати вкладені об'єкти. MDN є приклад глибокої заморозки, метод deepFreeze, який дозволить зробити повністю иммутабельный об'єкт.

Object.freeze() працює тільки з об'єктами ключ-значення, і в даний час немає можливості зробити иммутабельными такі об'єкти, як Date, Map або Set.

Тут є пропозиція щодо незмінним даними для майбутнього стандарту ECMAScript.

const vs. let
Єдина різниця між const і let в тому, що const обіцяє — переприсвоения не відбудеться.

З урахуванням вищевикладеного, const робить код більш читабельним. В межах області видимості const завжди посилається на той же об'єкт. Використовуючи let такої гарантії немає. Тому слід дотримуватися наступної практики:

  • Якщо це можливо — завжди використовуйте const за замовчуванням
  • let використовувати тоді, коли необхідно переприсвоение
  • var не повинен використовуватися взагалі
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.