В этом руководстве вы узнаете о двух разных типах значений в JavaScript, включая примитивные и ссылочные значения.
JavaScript имеет два разных типа значений:
- Примитивные значения;
- Ссылочные значения.
Примитивные значения — это атомарные фрагменты данных, а ссылочные значения — это объекты, которые могут состоять из нескольких значений.
Стек и куча памяти
Когда вы объявляете переменные, механизм JavaScript выделяет для них память в двух местах памяти: в стеке и в куче.
Статические данные — это данные, размер которых фиксируется во время компиляции. Статические данные включают в себя:
- Примитивные значения (null, undefined, boolean, number, string, symbol и BigInt)
- Ссылочные значения, которые относятся к объектам.
Поскольку размер статических данных не меняется, механизм JavaScript выделяет фиксированный объем памяти для статических данных и сохраняет их в стеке.
Например, в следующем примере объявляются две переменные и инициализируются их значения буквальной строкой и числом:
let name = 'John'; let age = 25;
Поскольку name и age являются примитивными значениями, движок JavaScript сохраняет эти переменные в стеке, как показано на следующем рисунке:
Обратите внимание, что строки являются объектами во многих языках программирования, включая Java и C#. Однако строки являются примитивными значениями в JavaScript.
В отличие от стека, JavaScript хранит объекты (и функции) в куче. Движок JavaScript не выделяет фиксированный объем памяти для этих объектов. Вместо этого он будет выделять больше места по мере необходимости.
В следующем примере определяются переменные name, age и person :
let name = 'John';
let age = 25;
let person = {
name: 'John',
age: 25,
};Внутри движок JavaScript выделяет память, как показано на следующем рисунке:
На этом рисунке JavaScript выделяет память в стеке для трех переменных name, age и person.
Движок JavaScript создает новый объект в куче памяти. Кроме того, он связывает переменную person в памяти стека с объектом в памяти кучи.
По этой причине мы говорим, что переменная person является ссылкой на объект.
Динамические свойства
Ссылочное значение позволяет добавлять, изменять или удалять свойства в любое время. Например:
let person = {
name: 'John',
age: 25,
};
// add the ssn property
person.ssn = '123-45-6789';
// change the name
person.name = 'John Doe';
// delete the age property
delete person.age;
console.log(person);Выход:
{ name: 'John Doe', ssn: '123-45-6789' }В отличие от ссылочного значения, примитивное значение не может иметь свойств. Это означает, что вы не можете добавить свойство к примитивному значению.
JavaScript позволяет добавлять свойство к примитивному значению. Однако никакого эффекта это не даст. Например:
let name = 'John'; name.alias = 'Knight'; console.log(name.alias); // undefined
Выход:
undefined
В этом примере мы добавляем свойство alias к примитивному значению name. Но когда мы обращаемся к свойству alias через примитивное значение name, оно возвращает undefined.
Копирование значений
Когда вы присваиваете примитивное значение одной переменной другой, механизм JavaScript создает копию этого значения и присваивает его переменной. Например:
let age = 25; let newAge = age;
В этом примере:
- Во-первых, объявите новую переменную
ageи инициализируйте ее значение25. - Во-вторых, объявите еще одну переменную
newAgeи присвойтеageпеременнойnewAge.
В фоновом режиме механизм JavaScript создает копию примитивного значения 25 и присваивает его переменной newAge.
На следующем рисунке показана память стека после присваивания:
В памяти стека newAge и age являются отдельными переменными. Если вы измените значение одной переменной, это не повлияет на другую.
Например:
let age = 25; let newAge = age; newAge = newAge + 1; console.log(age, newAge);
Когда вы присваиваете ссылочное значение одной переменной другой, механизм JavaScript создает ссылку, чтобы обе переменные ссылались на один и тот же объект в куче памяти. Это означает, что если вы измените одну переменную, это повлияет на другую.
Например:
let person = {
name: 'John',
age: 25,
};
let member = person;
member.age = 26;
console.log(person);
console.log(member);Как это работает.
Во-первых, объявите переменную person и инициализируйте ее значение с помощью объекта с двумя свойствами: name и age.
Во-вторых, назначьте переменную person переменной- member. В памяти обе переменные ссылаются на один и тот же объект, как показано на следующем рисунке:
В-третьих, измените свойство age объекта с помощью переменной- member :
Поскольку и переменные person и переменные- member ссылаются на один и тот же объект, изменение объекта через переменную- member также отражается в переменной person.
Заключение
- Javascript имеет два типа значений: примитивные и ссылочные.
- Вы можете добавлять, изменять или удалять свойства ссылочного значения, но не можете делать это с примитивным значением.
- При копировании примитивного значения из одной переменной в другую создается отдельная копия значения. Это говорит о том, что изменение значения одной переменной не влияет на другую.
- Копирование ссылки из одной переменной в другую создает ссылку, так что две переменные ссылаются на один и тот же объект. Это означает, что изменение объекта через одну переменную отражается в другой переменной.
