Добро пожаловать в серию статей «Понимание основ Javascript». В этом блоге мы попробуем разобраться с примитивными типами в Javascript.
Давайте перейдем к делу 🙂
В Javascript есть примитивные типы (примитивные значения), которые непосредственно представлены на самом низком уровне реализации языка.
В Javascript вообще есть два типа типов данных — примитивные и не примитивные (Object).
Все, что не относится к примитивным типам в JavaScript, является объектом. Функции, классы, массивы и типы, определяемые пользователем, — все это объекты.
Вы можете определить это с помощью оператора typeof, который может быть не совсем точным, но это достаточно хорошее приближение.
typeof 'hello' // string
typeof true // boolean
typeof 1 // number
typeof {} // object
typeof null // object
typeof undefined // undefined
typeof function () {} // function
typeof Symbol('hello') // symbol
Но здесь typeof null
является объектом, что на самом деле не верно, так как null — это примитивный тип.
typeof null // object
Это считается ошибкой в javascript.
Примитивные типы Javascript не являются объектами, и их значения неизменяемы. но переменные могут быть переназначены на новое значение.
При этом будет создана новая переменная, а сборщик мусора очистит старую.
пример неизменяемости примитивных типов
let a = 1;
let b = a;
// changing a will not change b
a = 2;
console.log(a); // 2
console.log(b); // 1
Поскольку и a
, и b
являются примитивными типами, они не связаны друг с другом.
При копировании b
из a
Javascript скопирует значение a
и присвоит его b
, так что изменение одного не изменит другого.
Давайте разберемся в этом подробнее
let a = 1;
Инициализация переменной с примитивным типом создаст новое значение в стеке и присвоит ему переменную. JavaScript создает примитивные типы в стеке с фиксированным пространством, в то время как объекты создаются в памяти кучи. Это происходит потому, что объекты мутабельны и могут быть изменены в любое время, занимая больше памяти.
Это так, потому что вы можете изменять объекты, добавляя новые свойства или изменяя существующие.
let a = 1;
let b = a;
Копирование примитивного типа создает новое значение в стеке и присваивает ему переменную. В этот момент a
и b
указывают на разные значения в стеке.
let a = 1;
let b = a;
a = 2;
Изменение значения a
не изменит значение b
, поскольку они указывают на разные адреса в стеке. В этот момент GC (Garbage Collector) удалит из стека адреса без ссылок.
Сравнение примитивных типов с объектами 👇🏾
let a = {
value: 1
};
let b = a;
// changing a will change b as they have the same reference
a.value = 2;
console.log(a.value); // 2
console.log(b.value); // 2
Как видно из примера выше, переменные Objects хранят не значения, а ссылки, поэтому изменение a
изменит b
, так как у них одна и та же ссылка.
Если примитивы не являются объектами, вы можете спросить, как мы получаем доступ к их свойствам, как в приведенном ниже примере?
'hello'.length // 5
Это не ошибка в javascript 😄.
На самом деле это одна из особенностей javascript. Примитивы не являются объектами, но ведут себя так, как будто они ими являются 🤔? Вот как это работает
Javascript сопоставляет примитивные типы с объектами-обертками, поэтому мы можем видеть свойство length
строки.
Что фактически создаст новый объект со значением "hello"
, и вы сможете получить доступ к свойству длины (или любому другому свойству строки) этого объекта. То же самое справедливо для двух других примитивных типов Boolean и Number.
let strObj = new String('hello')
typeof strObj // object
strObj.length // 5
// access the value of the object , which is the primitive value
strObj.valueOf() // hello
typeof strObj.valueOf() // string
Объект Boolean
let boolObj = new Boolean(true)
typeof boolObj // object
boolObj.valueOf() // true
typeof boolObj.valueOf() // boolean
Объект Number
let numObj = new Number(1)
typeof numObj // object
numObj.toFixed(2) // 1.00
numObj.valueOf() // 1
typeof numObj.valueOf() // number
Но как только мы получили доступ к свойству объекта, сборщик мусора удалит неиспользуемые объекты из памяти.
В Javascript существует 7 примитивных типов:
- неопределенный
- null
- булево
- число
- строка
- символ — es2015
- bigint — es2020
Тип данных symbol
является новым в es6.
JavaScript отличается тем, как он обращается с числами и строками (они представлены как самостоятельный примитивный тип), что
что не так часто встречается в устоявшихся языках программирования, таких как Java, которые, например, представляют числа по-разному в зависимости от их размера и свойств.
В Java плавающие числа имеют тип float, а целые числа — int, в то время как в javascript они оба представлены как Number.
Мы углубимся в эти примитивные типы и разницу в реализации javascript с другими языками программирования в следующем блоге этой серии.
Большое спасибо людям, которые помогли мне проверить формулировки в этом блоге.