Примитив (значение примитивного типа, примитивный тип данных) это данные, которые не являются объектом и не имеют методов. В JavaScript 6 простых типов данных: string, number, boolean, null, undefined, symbol (новое в ECMAScript 2015).

Чаще всего значение примитивного типа представлено в низкоуровневой реализации языка.

Все примитивы неизменяемы (immutable), то есть они не могут быть изменены. Важно не путать сам примитив с переменной, которой присвоено значение примитивного типа. Переменной может быть переприсвоено новое значение, но существующее значение примитивного типа не может быть изменено подобно объектам, массивам и функциям.

Пример

Этот пример поможет понять, что значения примитивных типов неизменяемы (immutable).

JavaScript

// Using a string method doesn't mutate the string
var bar = "baz";
console.log(bar);               // baz
bar.toUpperCase();
console.log(bar);               // baz

// Using an array method mutates the array
var foo = [];
console.log(foo);               // []
foo.push("plugh");
console.log(foo);               // ["plugh"]

// Assignment gives the primitive a new (not a mutated) value
bar = bar.toUpperCase();       // BAZ

Примитив может быть заменен, но он не может быть напрямую изменен.

Другой пример [ Step-by-step ]

Следующий пример поможет разобраться как JavaScript работает с примитивами.

JavaScript

// The Primitive 
let foo = 5;

// Defining a function that should change the Primitive value
function addTwo(num) {
   num += 2;
}
// Another function trying to do the same thing
function addTwo_v2(foo) {
   foo += 2;
}

// Calling our first function while passing our Primitive as an argument
addTwo(foo);
// Getting the current Primitive value
console.log(foo);   // 5

// Trying again with our second function...
addTwo_v2(foo);
console.log(foo);   // 5

Вы ожидали, что будет 7 вместо 5? Если так, тогда прочитайте, как работает этот код:

  • При вызове обеих функций addTwo и addTwo_v2, JavaScript ищет значение для идентификатора foo. JavaScript правильно определяет нашу переменную, созданную с помощью первого оператора
  • После этого JavaScript передает найденный аргумент в функцию в качестве параметра
  • Перед выполнением операторов в теле функции, JavaScript берет исходный переданный аргумент (который является примитивом) и создает его локальную копию. Эти копии, существующие только внутри областей функций, доступны через идентификаторы, указанные в определениях функций (num для addTwo, foo для addTwo_v2)
  • Затем выполняются операторы функций:
    • В первой функции был создан локальный аргумент num. Мы увеличиваем его значение на 2 (а не значение исходной переменной foo).
    • Во второй функции был создан локальный аргумент foo. Мы увеличиваем его значение на 2 (а не значение исходной (внешней) переменной foo).  Кроме того, в этой ситуации, внешняя переменная foo является недоступной никаким способом. Это связано с лексическими областями JavaScript и, как следствие, с затенением переменных. Локальная переменная foo скрывает внешнюю переменную foo. Чтобы получить больше информации, смотри Closures.
  • Таким образом, никакие изменения внутри наших функций не будут влиять на ИСХОДНУЮ foo вообще, так как мы работаем с ее копиями

Вот почему примитивы неизменяемы (immutable). Потому что мы не работаем над ними напрямую. Мы создаем копию и продолжаем работать с ней, не касаясь исходных значений.

Обертки примитивных типов в JavaScript

За исключением null и undefined, все примитивные значения имеют объектный аналог, который оборачивает значение примитивного типа:

  • String для string примитива.
  • Number для number примитива.
  • Boolean для Boolean примитива.
  • Symbol для Symbol примитива.

Метод valueOf() типа обертки возвращает значение примитивного типа.

См. также

Общие сведения

Метки документа и участники

Внесли вклад в эту страницу: bsergey, aleks43
Обновлялась последний раз: bsergey,