В javascript переменная может хранить два типа значений: примитивные и ссылочные. Итак, прежде чем мы их обсудим, давайте сначала обсудим две важные концепции - стек и куча.
Куча
С точки зрения непрофессионала, стопка - это стопка объектов. В вычислениях стеки архитектуры - это, по сути, области памяти, в которые данные добавляются или удаляются в порядке «последним пришел - первым обслужен» (LIFO).
Куча
С точки зрения непрофессионала, куча - это неопрятное собрание вещей, скопившихся наугад. В вычислениях куча архитектуры - это область динамически выделяемой памяти, которая автоматически управляется операционной системой.
А теперь вернемся к нашей основной теме.
Примитивные типы
В Javascript есть шесть примитивных типов: null, undefined, boolean, string, number, symbol.
Размер примитивных значений фиксирован. Вот почему javascript хранит примитивные значения в стеке. Когда вы назначаете переменную этого типа другой переменной, новая переменная копирует значение. Возьмем пример.
let x = 1; let y = x; console.log(x, y); // 1 1 x = 2; console.log(x, y); // 2 1 y = 3; console.log(x, y); // 2 3
В строке 5 мы изменили значение x
. Но это не изменило значение y
. Потому что y
скопировал значение x
.
Типы ссылок
В javascript есть два ссылочных типа: объект и массив. Массивы также являются объектами, так что технически одного типа. Размер ссылочных типов является динамическим, поэтому javascript хранит ссылочные значения в куче. Когда мы создаем объект и присваиваем ему какое-то значение. Значение не сохраняется непосредственно в переменной, вместо этого в этой переменной хранится ссылка на значение. Возьмем пример
let student1 = {name: "john", age: 20}; let student2 = student1; console.log(student1); // {name: "john", age: 20} console.log(student2); // {name: "john", age: 20} student2.name = "doe"; console.log(student1); // {name: "doe", age: 20} console.log(student2); // {name: "doe", age: 20}
В этом примере мы изменили значение student2
в строке 7, а также изменили значение student1
. Это потому, что и student1
, и student2
ссылаются на одно и то же значение. Таким образом, изменение student1
повлияет на student2
и наоборот.
Теперь вопрос в том, как побороть эту проблему. Решение состоит в том, чтобы создать новую ссылку для нового объекта. Таким образом, новый объект будет указывать на свой собственный объект, а не перекрывать друг друга. Мы можем создать новую ссылку, используя оператор распространения. Возьмем пример.
let student1 = {name: "john", age: 20}; let student2 = {...student1}; console.log(student1); // {name: "john", age: 20} console.log(student2); // {name: "john", age: 20} student2.name = "doe"; console.log(student1); // {name: "john", age: 20} console.log(student2); // {name: "doe", age: 20}
Таким образом мы можем решить проблему перекрытия.
Надеюсь, статья вам понравилась. Не стесняйтесь оставлять свои вопросы и комментарии ниже.