Недавно я мучал доктора Бага небольшим скриптецом. Суть была показать как можно в отдельном модуле организовать обменник данными. Просто метод положить и метод достать, все просто. Как обычно я не задумываясь организовал это дело через коллекцию в константе, и в итоге пришлось разъяснять почему так можно, ибо кажется что менять константу нельзя. Посему я решил просто поизголятся и углубиться в эту теорию несколько глубже, хоть тема и кажется тривиальной.
Первое что может сбить с толку это ощущение что переменная и есть объект (перепрочтите заголовок). Но это не совсем так, переменные являются представлением объекта, что то вроде портала через который можно достать объект и помучать его. В этом плане 2 переменных, содержащих один объект, это два портала с одной точкой выхода.
А оператор присвоения (знак '=') это настройка телепорта на объект. Ага, если слева находится именно переменная/константа (а не конструкция посложнее) то объект и не меняется никаким образом. Разница между присвоением и конструкцией посложнее:
variable = [] # присвоение
variable.field = [] # метод field= объекта
variable['field'] = [] # метод []= объекта
Пример того как присваивание не меняет объект, но иная конструкция меняет:
array = [ { value: 'value' } ]
array2 = array
element = array[0]
element = { value: 'not value (obviously!)' }
p array # => [{:value=>"value"}] Мы назначили на переменную element новое значение, сам массив не постродал
array[0] = { value: 'not value (obviously!)' }
p array # => [{:value=>"not value (obviously!)"}] Мы использовали оператор []= который поменял исходный массив
array2 = []
p array # => [{:value=>"not value (obviously!)"}] Мы переприсвоили переменную, а не пересоздали объект
Позвольте мозгу поработать над этой идеей, ибо дальше будет продолжение. Так вот - константы. Единственное отличие константы от переменной это невозможность повторного использования оператора присвоения. Мда, это все. Тот же пример с константой:
ARRAY = [ { value: 'value' } ]
array2 = ARRAY
element = ARRAY[0]
element = { value: 'not value (obviously!)' }
p ARRAY # => [{:value=>"value"}]
ARRAY[0] = { value: 'not value (obviously!)' }
p ARRAY # => [{:value=>"not value (obviously!)"}]
array2 = []
p ARRAY # => [{:value=>"not value (obviously!)"}]
То есть разница между первым и вторым только в присвоении, как в следующем примере:
variable = []
variable = []
CONSTANT = []
CONSTANT = [] # Ошибка
И хоть я и пишу это про руби, те же 2 примера работают так же и в яваскрипте. Переменная:
var array = [ { value: 'value' } ];
var array2 = array;
var element = array[0];
element = { value: 'not value (obviously!)' };
console.log(array); // => [ { value: 'value' } ] Мы назначили на переменную element новое значение, сам массив не постродал
array[0] = { value: 'not value (obviously!)' };
console.log(array); // => [ { value: 'not value (obviously!)' } ] Мы использовали оператор []= который поменял исходный массив
array2 = [];
console.log(array); // => [ { value: 'not value (obviously!)' } ] Мы переприсвоили переменную, а не пересоздали объект
Константа:
const ARRAY = [ { value: 'value' } ];
var array2 = ARRAY;
var element = ARRAY[0];
element = { value: 'not value (obviously!)' };
console.log(ARRAY); // => [ { value: 'value' } ]
ARRAY[0] = { value: 'not value (obviously!)' };
console.log(ARRAY); // => [ { value: 'not value (obviously!)' } ]
array2 = [];
console.log(ARRAY); // => [ { value: 'not value (obviously!)' } ]
Таааак выходит что константа практически не влияет на возможность изменения объекта. В данном случае надо делить типы объектов на изменияемые и неизменяемые. Так например число неизменяемое, а массив изменяемое. Почему? Да потому что для первого не существующет метода, который бы мог изменить сам объект, вместо этого всегда возвращается новый объект в результате вызова. Например в Руби строки изменяемые, а в js нет:
CONSTANT = 'cat'
CONSTANT[0] = 'b'
puts CONSTANT # => bat
const CONSTANT = 'cat';
CONSTANT[0] = 'b'; // Может repl.it голимый, может так и положено, но ошибки небыло
console.log(CONSTANT); // 'cat'
И единственный выход в js это создать новую строку на основе той, что хранится в константе. Это, пожалуй, все. Все примеры, как вы уже поняли, я проверял на
этом сайте.