Dlaczego mogę zmienić wartość stałej w javascript

Wiem, że ES6 nie jest jeszcze standaryzowany, ale wiele przeglądarek obsługuje obecnie const słowo kluczowe w JS.

W spec pisze się, że:

Wartość stałej nie może się zmienić poprzez ponowne przypisanie, a stała nie może być ponownie zadeklarowana. Z tego powodu, chociaż jest Można zadeklarować stałą bez jej inicjalizacji, byłoby bez sensu.

A kiedy robię coś takiego:

const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];

Widzę, że wszystko jest w porządku xxx jest nadal 6 i yyy jest [].

Ale jeśli to zrobię yyy.push(6); yyy.push(1);, moja stała tablica została zmieniona. W tej chwili jest [6, 1] i przy okazji nadal nie mogę tego zmienić za pomocą yyy = 1;.

To błąd, czy coś mi umyka? Wypróbowałem go w najnowszym chrome i FF29

Author: Felix Kling, 2014-05-03

5 answers

Dokumentacja stwierdza:

...stała nie może się zmienić poprzez ponowne przypisanie
...stała nie może być ponownie zadeklarowana

Kiedy dodajesz do tablicy lub obiektu, nie przypisujesz ani nie deklarujesz stałej, jest ona już zadeklarowana i przypisana, po prostu dodajesz do" listy", na którą wskazuje stała.

Więc to działa dobrze

const x = {};

x.foo = 'bar';

console.log(x); // {foo : 'bar'}

I to

const y = [];

y.push('foo');

console.log(y); // ['foo'];

Ale żadne z nich

const x = {};
x = {foo: 'bar'}; // error - re-assigning

const y = ['foo'];
const y = ['bar']; // error - re-declaring

const foo = 'bar'; 
foo = 'bar2';       // error - can not re-assign
var foo = 'bar3';   // error - already declared
function foo() {};  // error - already declared
 68
Author: adeneo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 20:50:55

Dzieje się tak, ponieważ twoja stała przechowuje odniesienie do tablicy. Kiedy dołączasz coś do tablicy, nie modyfikujesz swojej stałej wartości, ale tablicy, na którą wskazuje. To samo stanie się, jeśli przypiszesz obiekt do stałej i spróbujesz zmodyfikować jakąkolwiek jego właściwość.

Jeśli chcesz zamrozić tablicę lub obiekt, aby nie można było jej modyfikować, możesz użyć Object.freeze metoda, która jest już częścią ECMAScript 5.

const x = Object.freeze(['a'])
x.push('b')
console.log(x) // ["a"]
 15
Author: Guilherme Sehn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-11 14:34:56

Jest to zgodne zachowanie z każdym językiem programowania, jaki przychodzi mi do głowy.

Rozważ, że C - tablice są tylko wskazówkami. Stała tablica oznacza tylko, że wartość wskaźnika nie zmieni się - ale w rzeczywistości dane zawarte pod tym adresem są dowolne.

W javascript można wywoływać metody obiektów stałych(oczywiście-w przeciwnym razie obiekty stałe nie służyłyby za wiele!) Te metody mogą mieć efekt uboczny modyfikacji obiektu. Od tablice w javascript są obiektami, to zachowanie odnosi się również do nich.

Wszystko, co masz pewność, to to, że stała zawsze będzie wskazywać na ten sam obiekt. Właściwości samego obiektu można dowolnie zmieniać.

 5
Author: thorsday,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 20:55:07

Deklaracja const tworzy odniesienie tylko do odczytu do wartości. Nie oznacza to, że posiadana wartość jest niezmienna, tylko, że identyfikator zmiennej nie może być ponownie przypisany. Na przykład w przypadku, gdy zawartość jest obiektem, oznacza to, że zawartość obiektu (np. jego parametry) może zostać zmieniona.

Dodatkowo ważna uwaga:

Stałe Globalne nie stają się właściwościami obiektu window ...

Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

 0
Author: Benjamin G. West,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-23 12:14:45

Myślę, że to da ci więcej jasności w tej sprawie: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0 .

Sprowadza się do const zawsze wskazującego ten sam adres w pamięci. Możesz zmienić wartość przechowywaną w tym adresie, ale nie możesz zmienić adresu, który wskazuje const.

Definicja const, o której wspomniałeś, będzie prawdziwa, gdy const wskazuje adres, który zawiera prymitywną wartość . To ponieważ nie można przypisać wartości const bez zmiany jej adresu (ponieważ tak działa przypisywanie prymitywnych wartości) i zmiana adresu const jest niedozwolona.

Gdzie tak, jakby const wskazywało na nie-prymitywną wartość, można edytować wartość adresu.

 0
Author: Zyxmn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 20:43:48