Подтвердить что ты не робот

Понимание неизменяемой переменной Javascript

Я пытаюсь понять, что означает неизменяемая переменная Javascript. Если я могу сделать:

var x = "astring";
x = "str";
console.log(x); //logs str` , then why it is immutable?

Единственный ответ, который я могу думать (от небольшого числа CI знаю), состоит в том, что var x является указателем на блок памяти со значением "astring", а после 2-го оператора он указывает на другой блок со значением "ул". Это тот случай?

И бонусный вопрос: меня смутили значения типов Javascript. Все объекты переменных находятся под капотом? Четное число и строки?

4b9b3361

Ответ 1

Значения неизменяемы; переменные не являются; они содержат ссылку на их (примитивные) значения.

Три примитивных типа string, number и boolean имеют соответствующие типы, экземплярами которых являются объекты: String, Number, Boolean.
Их иногда называют типами обертки.

Следующие значения primitive:

  • Строки: "привет"
  • Числа: 6, 3.14 (все числа в JavaScript являются плавающей точкой)
  • Booleans: true, false
  • null: обычно явно назначается
  • undefined: обычно значение по умолчанию (автоматически назначено)

Все остальные значения являются объектами, включая обертки для примитивов.

Итак:

  • Объекты изменяются по умолчанию
  • Объекты имеют уникальные идентификаторы и сравниваются по ссылке
  • Переменные содержат ссылки на объекты
  • Примитивы неизменяемы.
  • Примитивы сравниваются по значению, у них нет индивидуальных идентификаторов

Вы можете найти The Secret Life of JavaScript Primitives хорошее объяснение.

Кроме того, в ES6 есть новое ключевое слово const, которое создает постоянную константу, доступную только для чтения, которая не может изменять значение посредством назначения или быть повторно объявлен, пока выполняется script.

Надеюсь, это поможет!

Ответ 2

Во-первых, в C "Строка представляет собой массив символов с последним elem = '\ 0'". Они изменяемы.
Если вы объявляете и инициализируете строку в C следующим образом:

char str[] = "Foo";

В основном вы делаете резервирование 4 байтов (возможно, 8 бит-байт, не против, возможно, если это причинит вам боль). Слово str служит указателем на первый элемент этого массива. Итак, если вы сделаете так:

str[0] or *(str) = 'G'

то он будет мутировать значение по этому адресу вместо создания нового массива. Вы можете проверить его, распечатав адрес str. В обоих случаях он будет таким же.

Теперь в случае JavaScript строка является примитивным типом. Все операции с строкой выполняются по значению, а не по ссылке. Таким образом, выполнение этого приведет к истинному.

var str1 = "foo";
var str2 = "foo";
str1 === str2; => true

Инициализация строки требует, чтобы буфер соответствовал "foo" и связывает имя str1 с ним. Что делает их неизменными, так это то, что вы не можете изменить этот буфер. Итак, вы не можете этого сделать:

str1[0] = 'G'

Выполнение этой команды не приведет к предупреждению или ошибке в нестрогом режиме, но не изменит str1. Вы можете проверить его на

console.log(str1) => "foo"

Но если вы сделаете так:

str1 = "goo"

то, что вы на самом деле делаете, заключается в том, что вы запрашиваете новый буфер, чтобы он соответствовал "goo" и привязывал идентификатор str1 к нему. Никаких изменений в этом старом буфере, содержащем "foo" .

Итак, что происходит с "foo" ?

Java Script имеет автоматический сборщик мусора. Когда он видит некоторый фрагмент памяти, на который больше нельзя ссылаться ни одним идентификатором, либо... тогда он считает, что память свободна.

То же самое происходит с числом, булевым. Теперь об объектах-оболочках! Всякий раз, когда вы пытаетесь получить доступ к свойству в строке следующим образом:

str1.length;

Какой JavaScript создает новый объект с использованием класса String и вызывает методы в строке. Как только вызов функции вернется, объект будет уничтожен. Ниже приведен код ниже:

var str = "nature"; 
str.does = "nurtures"; //defining a new property; 
console.log(str.does) => undefined

потому что объект был уничтожен. Попробуйте это!

var str = new String("Nature");
str.does = "nurtures";
console.log(str) =>  ??

эта str действительно является объектом...

Заключение: В C, в одной области, имя переменной служит в качестве указателя. Таким образом, int, float, string все изменяемы. Но в Java Script имя переменной примитивного типа служит как значение не как ссылка

Ссылки: С++ primer plus, Java Script Окончательное руководство, C Стивеном Кочаном

Ответ 3

Вы правы. Строки (и числа) неизменяемы в java script (и многих других языках). Переменные - это ссылки на них. Когда вы "изменяете значение переменной", вы меняете строку (или что-то еще), которую ссылается переменной, а не само значение.