Этот вопрос проверяет глубокое понимание системы типов JavaScript, различий между примитивами и объектами, и механизмов работы с ними.
JavaScript различает примитивы (числа, строки, boolean, null, undefined, symbol, bigint) и объекты. Примитивы хранятся по значению, иммутабельны и сравниваются по значению. Объекты хранятся по ссылке, мутабельны и сравниваются по ссылке. Примитивы могут временно вести себя как объекты через обертки.
Понимание различий между примитивами и объектами критически важно для написания корректного JavaScript кода.
JavaScript имеет 7 примитивных типов:
javascript
// Примитивные значения
const number = 42; // number
const string = "hello"; // string
const boolean = true; // boolean
const nullValue = null; // null
const undefinedValue = undefined; // undefined
const symbol = Symbol("id"); // symbol
const bigInt = 9007199254740991n; // bigintВсе остальные значения являются объектами:
javascript
// Объекты
const object = { key: "value" };
const array = [1, 2, 3];
const functionObj = function() {};
const date = new Date();
const regex = /pattern/;Примитивы хранятся по значению:
javascript
let a = 10;
let b = a; // b получает копию значения
a = 20;
console.log(a); // 20
console.log(b); // 10 - не изменилосьОбъекты хранятся по ссылке:
javascript
let obj1 = { value: 10 };
let obj2 = obj1; // obj2 получает ссылку на тот же объект
obj1.value = 20;
console.log(obj1.value); // 20
console.log(obj2.value); // 20 - изменилось тоже!Примитивы сравниваются по значению:
javascript
const a = "hello";
const b = "hello";
console.log(a === b); // true - одинаковые значения
const num1 = 5;
const num2 = 5;
console.log(num1 === num2); // trueОбъекты сравниваются по ссылке:
javascript
const obj1 = { value: 10 };
const obj2 = { value: 10 };
const obj3 = obj1;
console.log(obj1 === obj2); // false - разные ссылки
console.log(obj1 === obj3); // true - одинаковые ссылкиПримитивы иммутабельны:
javascript
let str = "hello";
str[0] = "H"; // Не сработает
console.log(str); // "hello" - не изменилось
// Создается новая строка
str = str.toUpperCase();
console.log(str); // "HELLO" - новый примитивОбъекты мутабельны:
javascript
const obj = { value: 10 };
obj.value = 20; // Изменяет существующий объект
obj.newProp = "new"; // Добавляет свойство
console.log(obj); // { value: 20, newProp: "new" }Примитивы используют обертки:
javascript
const str = "hello";
console.log(str.toUpperCase()); // "HELLO"
// Что происходит под капотом:
// 1. Создается временный String объект
// 2. Вызывается метод toUpperCase()
// 3. Временный объект удаляетсяОбъекты используют методы напрямую:
javascript
const arr = [1, 2, 3];
arr.push(4); // Метод вызывается напрямую
console.log(arr); // [1, 2, 3, 4]javascript
// Примитив - передается по значению
function modifyPrimitive(x) {
x = x * 2;
return x;
}
let num = 5;
modifyPrimitive(num);
console.log(num); // 5 - не изменился
// Объект - передается по ссылке
function modifyObject(obj) {
obj.value = obj.value * 2;
}
let myObj = { value: 5 };
modifyObject(myObj);
console.log(myObj.value); // 10 - изменилсяjavascript
// Поверхностное копирование объектов
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
shallowCopy.a = 10; // Не влияет на original
shallowCopy.b.c = 20; // Влияет на original!
console.log(original.b.c); // 20
// Глубокое копирование
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 30;
console.log(original.b.c); // 20 - не изменилосьjavascript
// typeof для примитивов
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol()); // "symbol"
console.log(typeof 42n); // "bigint"
console.log(typeof null); // "object" (известная ошибка)
// typeof для объектов
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){});// "function"javascript
// Явное создание оберток
const strPrimitive = "hello";
const strObject = new String("hello");
console.log(typeof strPrimitive); // "string"
console.log(typeof strObject); // "object"
console.log(strPrimitive === strObject); // falsejavascript
// JavaScript автоматически упаковывает примитивы
const str = "hello";
console.log(str.length); // 5 - временный String объект
// Эквивалентно:
const tempStr = new String(str);
console.log(tempStr.length);
tempStr = null; // Удаление временного объектаВывод: Примитивы и объекты в JavaScript имеют фундаментальные различия в хранении, сравнении, мутабельности и поведении. Понимание этих различий помогает избежать распространенных ошибок и писать более эффективный код.