Słowo kluczowe „const” nie powoduje, że wartość jest niezmienna. Co to znaczy?

85

Jest to definicja const w Exploring ES6 dr Axel Rauschmayer:

constdziała jak let, ale deklarowana zmienna musi zostać natychmiast zainicjowana, z wartością, której nie można później zmienić . […]

const bar = 123;
bar = 456;  // TypeError: `bar` is read-only

a potem pisze

Pułapka: const nie czyni wartości niezmienną

const oznacza tylko, że zmienna ma zawsze tę samą wartość, ale nie oznacza, że ​​sama wartość jest lub stanie się niezmienna.

Nie jestem zdezorientowany tą pułapką. Czy ktoś może jasno określić consttę pułapkę?

Mukund Kumar
źródło
38
MDN wyjaśnienie jest jasne: „Deklaracja const tworzy odwołanie do wartości tylko do odczytu To nie znaczy, że wartość posiada ona jest niezmienna, tylko że zmienna identyfikator nie może być przeniesiony Na przykład, w przypadku gdy zawartość jest.. Obiekt oznacza to, że sam obiekt nadal można zmienić . " (moje podkreślenie)
Gerardo Furtado
4
Oznacza to, że jeśli wartość jest zmienna (np. Jeśli jest to obiekt), to nadal możesz zmodyfikować ten obiekt (np. Zaktualizować, dodać, usunąć właściwości).
Felix Kling
2
const x = "immutable"jest niezmienna, ponieważ Stringjest niezmienna. constzabrania jedynie zmiany przydziału.
3
@ibrahimmahrir: przechodząc do odniesienia (co robi JavaScript dla obiektów) nie jest taka sama jak przejściu przez odniesienia (która opisuje relację między wiązaniami, wartość jest nieistotna).
Felix Kling
2
@ibrahimmahrir: Tak, w tym problem. Termin przekazywanie odniesienia ma bardzo specyficzne znaczenie .
Felix Kling

Odpowiedzi:

97

MDN ładnie to podsumowuje:

Deklaracja const tworzy odwołanie tylko do odczytu do wartości. Nie oznacza to, że wartość, którą posiada, jest niezmienna, po prostu nie można ponownie przypisać identyfikatora zmiennej. Na przykład w przypadku, gdy treść jest przedmiotem, oznacza to, że sam obiekt można nadal zmienić.

Bardziej zwięźle: const tworzy niezmienne powiązanie.

Innymi słowy: const, podobnie jak var, daje modyfikowalny fragment pamięci, w którym coś przechowujesz. Jednak const nakazuje, abyś nadal odnosił się do tego samego fragmentu pamięci - nie możesz ponownie przypisać zmiennej do innego fragmentu pamięci, ponieważ odwołanie do zmiennej jest stałe.

Aby naprawdę stworzyć coś stałego i niezmiennego po zadeklarowaniu tego, musisz użyć czegoś takiego jak Object.freeze(). Jest to jednak płytkie i działa tylko na parach klucz / wartość. Zamrożenie całego obiektu wymaga nieco więcej wysiłku. Robienie tego wielokrotnie w skuteczny sposób jest jeszcze trudniejsze. Jeśli naprawdę tego potrzebujesz, polecam wypróbowanie czegoś takiego jak Immutable.js

Mike Post
źródło
20
W terminologii C: jeśli norma var xto a struct Object *x, a const xjest struct Object *const x. Nie można zmienić wskaźnika; rzecz, na którą wskazuje, może.
Załóż pozew Moniki
151

Kiedy tworzysz coś constw JavaScript, nie możesz zmienić przypisania samej zmiennej, aby odwoływała się do czegoś innego. Jednak zmienna może nadal odwoływać się do modyfikowalnego obiektu.

const x = {a: 123};

// This is not allowed.  This would reassign `x` itself to refer to a
// different object.
x = {b: 456};

// This, however, is allowed.  This would mutate the object `x` refers to,
// but `x` itself hasn't been reassigned to refer to something else.
x.a = 456;

W przypadku prymitywów, takich jak łańcuchy i liczby, constłatwiej jest zrozumieć, ponieważ nie modyfikujesz wartości, ale zamiast tego przypisujesz nową wartość do zmiennej.

Candy Gumdrop
źródło
18
Ta odpowiedź jest znacznie lepsza niż zaakceptowana. Bardziej zwięzły i zawiera rzeczywisty przykładowy kod. (Innymi słowy, przechodzi do
rzeczy
16

Rebinding

consta letdeklaracje kontrolują, czy ponowne wiązania (inaczej przypisania) między identyfikatorami i wartościami są dozwolone:

const x = "initial value";
let y = "initial value";

// rebinding/reassignment

try { x = "reassignment" } catch(e) { console.log(x) } // fails

y = "reassignment"; // succeeds
console.log(y);

Niezmienność

Niezmienność jest kontrolowana na poziomie typu. Objectjest typem zmiennym, podczas gdy Stringjest typem niezmiennym:

const o = {mutable: true};
const x = "immutable";

// mutations

o.foo = true; // succeeds
x[0] = "I"; // fails

console.log(o); // {mutable: true, foo: true}
console.log(x); // immutable


źródło
1

const oznacza: nie możesz zmienić początkowo przypisanej wartości.

Najpierw zdefiniuj, jaka jest wartość w js. Wartością mogą być: wartości logiczne, ciągi znaków, liczby, obiekty, funkcje i wartości niezdefiniowane.

Na przykład: Ludzie dzwonią do Ciebie, podając Twoje imię, to się nie zmienia. Jednak zmieniasz ubranie. Wiązania pomiędzy ludźmi a ty masz na imię. Reszta może się zmienić. Przepraszam za dziwny przykład.

Podam więc kilka przykładów:

// boolean
const isItOn = true;
isItOn = false;           // error

// number
const counter = 0;
counter++;                // error

// string
const name = 'edison';
name = 'tesla';           // error

// objects
const fullname = {
  name: 'albert',
  lastname: 'einstein'
};

fullname = {              // error
  name: 'werner',
  lastname: 'heisenberg'
};
// NOW LOOK AT THIS:
//
// works because, you didn't change the "value" of fullname
// you changed the value inside of it!
fullname.name = 'hermann';

const increase = aNumber => ++aNumber;
increase = aNumber => aNumber + 1;      // error

// NOW LOOK AT THIS:
//
// no error because now you're not changing the value
// which is the decrease function itself. function is a
// value too.
let anotherNumber = 3;
const decrease = () => --anotherNumber;

anotherNumber = 10;             // no error
decrease();                     // outputs 9

const chaos = undefined;
chaos = 'let there be light'    // error

const weird = NaN;
weird = 0                       // error

Jak widać, o ile nie zmieniasz „pierwszej” przypisanej wartości na stałą, nie ma błędu. Ilekroć próbujesz zmienić pierwszą przypisaną wartość na coś innego, denerwuje się i powoduje błąd.

To jest druga rzecz, którą możesz wiedzieć podczas używania const. Oznacza to, że powinien zostać zainicjowany na wartość w swojej deklaracji lub będzie zły.

const orphan;                    // error
const rich = 0;                  // no error
Inanc Gumus
źródło
0

ES6/ ES2015 constsłowo kluczowe:

Słowo constkluczowe służy do zadeklarowania zmiennej o zakresie blokowym (jak deklarowanie za pomocą let). Różnica między deklarowaniem zmiennej za pomocą consti letjest następująca:

  1. Zadeklarowanej zmiennej constnie można ponownie przypisać .
  2. Zmienna zadeklarowana za pomocą constmusi zostać przypisana podczas deklaracji . Jest to logiczna konsekwencja poprzedniego punktu, ponieważ zmiennej zadeklarowanej za constpomocą nie można ponownie przypisać, dlatego musimy przypisać ją dokładnie raz, kiedy deklarujemy zmienną .

Przykład:

// we declare variable myVariable
let myVariable;

// first assignment
myVariable = 'First assingment';
// additional assignment
myVariable = 'Second assignment';

// we have to declare AND initialize the variable at the same time
const myConstant = 3.14;

// This will throw an error
myConstant = 12;

W powyższym przykładzie możemy zaobserwować:

  1. Zmienną myVariablezadeklarowaną za pomocą letmożna najpierw zadeklarować, a następnie przypisać.
  2. Zmienna myConstantzadeklarowana za pomocą constmusi zostać zadeklarowana i przypisana w tym samym czasie.
  3. Kiedy próbujemy ponownie przypisać zmienną myConstant, otrzymujemy następujący błąd:

Uncaught TypeError: przypisanie do stałej zmiennej

Uwaga: zmienna przypisana constjest nadal modyfikowalna:

Zmiennej zadeklarowanej constpo prostu nie można ponownie przypisać, nadal można ją modyfikować . Bycie mutowalnym oznacza, że ​​struktura danych (obiekt, tablica, mapa itp.), Która została przypisana do constzmiennej, nadal może zostać zmieniona (tj. Zmutowana). Przykłady mutacji to:

  1. Dodawanie / usuwanie / zmiana właściwości obiektu
  2. Zmiana wartości tablicy przy określonym indeksie tablicy

Jeśli naprawdę chcesz, aby obiekt nie był zmienny, będziesz musiał użyć czegoś takiego jak Object.freeze(). Jest to metoda, która zamraża obiekt. Zamrożonego obiektu nie można już zmienić ani dodać nowych właściwości.

Przykład:

const obj = {prop1: 1};

obj.prop1 = 2;
obj.prop2 = 2;

console.log(obj);

// We freeze the object here
Object.freeze(obj);

obj.prop1 = 5;
delete obj.prop2;

// The object was frozen and thus not mutated
console.log(obj);

Willem van der Veen
źródło