← Назад к вопросам

Что такое тег link в HTML?

2.0 Middle🔥 181 комментариев
#HTML и CSS

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему можно что-нибудь сделать с мутабельными типами данных?

Вопрос о мутабельности - это один из фундаментальных принципов в программировании. В JavaScript есть мутабельные (изменяемые) и иммутабельные (неизменяемые) типы. Понимание различия критично для написания надёжного кода.

Мутабельные vs Иммутабельные типы

// Примитивы - ИММУТАБЕЛЬНЫ
let num = 5;
num = 10; // создали новое значение, старое не изменилось

let str = "hello";
str = "hello world"; // создали новую строку

// Объекты - МУТАБЕЛЬНЫ
const obj = { name: "John" };
obj.name = "Jane"; // изменили существующий объект
obj.age = 30; // добавили новое свойство

const arr = [1, 2, 3];
arr[0] = 99; // изменили элемент массива
arr.push(4); // добавили элемент

Разница: примитивы вы не можете изменить на месте, объекты можете.

Почему мутабельность проблематична

1. Непредсказуемые побочные эффекты

// Проблема
function doubleNumbers(arr) {
  return arr.map(n => n * 2); // OK
}

const numbers = [1, 2, 3];
const doubled = doubleNumbers(numbers);
console.log(numbers); // [1, 2, 3] - не изменился

// НО
function doubleArrayMutating(arr) {
  arr[0] = arr[0] * 2; // мутируем!
  arr[1] = arr[1] * 2;
  arr[2] = arr[2] * 2;
  return arr;
}

const numbers2 = [1, 2, 3];
const doubled2 = doubleArrayMutating(numbers2);
console.log(numbers2); // [2, 4, 6] - изменился! Неожиданно!

2. Баги в React из-за мутации

// ПЛОХО - мутируем state
function BadComponent() {
  const [user, setUser] = useState({ name: "John", age: 30 });

  const handleNameChange = (newName: string) => {
    user.name = newName; // МУТАЦИЯ!
    setUser(user); // React не заметит изменений
  };

  return (
    <>
      <p>{user.name}</p>
      <button onClick={() => handleNameChange("Jane")}>Change</button>
    </>
  );
  // Текст НЕ обновится, потому что объект был изменён на месте
  // React сравнивает ссылки, не содержимое
}

// ХОРОШО - создаём новый объект
function GoodComponent() {
  const [user, setUser] = useState({ name: "John", age: 30 });

  const handleNameChange = (newName: string) => {
    setUser(prev => ({ ...prev, name: newName })); // новый объект
  };

  return (
    <>
      <p>{user.name}</p>
      <button onClick={() => handleNameChange("Jane")}>Change</button>
    </>
  );
  // Текст обновится, потому что это новый объект
}

Правило: не мутируй state

// Массивы
const [items, setItems] = useState([1, 2, 3]);

// ПЛОХО
items.push(4);
setItems(items);

// ХОРОШО
setItems([...items, 4]);
setItems(prev => [...prev, 4]);

// Удаление
// ПЛОХО
items.splice(0, 1);
setItems(items);

// ХОРОШО
setItems(items.filter((_, i) => i !== 0));
setItems(prev => prev.slice(1));

// Изменение элемента
// ПЛОХО
items[0] = 99;
setItems(items);

// ХОРОШО
setItems(items.map((v, i) => i === 0 ? 99 : v));
setItems(prev => [99, ...prev.slice(1)]);

Объекты и вложенные структуры

const [user, setUser] = useState({
  name: "John",
  address: {
    city: "Moscow",
    zip: "123456"
  }
});

// ПЛОХО - мутируем вложенный объект
user.address.city = "SPB";
setUser(user);

// ХОРОШО - создаём новые объекты на каждом уровне
setUser({
  ...user,
  address: {
    ...user.address,
    city: "SPB"
  }
});

// ИЛИ используйте immer
import produce from 'immer';

setUser(produce(draft => {
  draft.address.city = "SPB";
}));

Методы массивов: мутирующие vs безопасные

const arr = [1, 2, 3, 4, 5];

// МУТИРУЮЩИЕ методы (изменяют оригинальный массив)
arr.push(6);           // добавляет в конец
arr.pop();             // удаляет последний
arr.shift();           // удаляет первый
arr.unshift(0);        // добавляет в начало
arr.splice(0, 1);      // удаляет и заменяет
arr.reverse();         // разворачивает
arr.sort();            // сортирует
arr.fill(0);           // заполняет значением

// БЕЗОПАСНЫЕ методы (возвращают новый массив)
const arr2 = arr.slice(0, 2);        // подмассив
const arr3 = arr.concat([6, 7]);     // объединение
const arr4 = arr.map(x => x * 2);    // трансформация
const arr5 = arr.filter(x => x > 2); // фильтрация
const arr6 = [0, ...arr];            // добавление в начало
const arr7 = [...arr, 6];            // добавление в конец

Когда можно мутировать

1. Объекты которые только создали

function createUser(name, email) {
  const user = {}; // новый объект
  user.name = name;   // мутация OK - никто не использует
  user.email = email;
  user.id = Math.random();
  return user; // возвращаем сформированный объект
}

2. Внутри функции перед возвратом

function processArray(arr) {
  const result = [...arr]; // копируем
  result.sort(); // мутируем копию
  return result; // возвращаем
}

const original = [3, 1, 2];
const sorted = processArray(original);
console.log(original); // [3, 1, 2] - не изменился
console.log(sorted);   // [1, 2, 3]

3. Локальные переменные в функции

function calculateSum(arr) {
  let sum = 0;          // локальная переменная
  for (let num of arr) {
    sum += num;         // мутируем локальную переменную
  }
  return sum;           // OK
}

Структурное копирование

// Поверхностное копирование (shallow copy)
const original = { name: "John", address: { city: "Moscow" } };
const copy1 = { ...original };
const copy2 = Object.assign({}, original);

copy1.name = "Jane"; // OK
copy1.address.city = "SPB"; // ПЛОХО - изменит и original!

// Глубокое копирование (deep copy)
const deepCopy = JSON.parse(JSON.stringify(original));
// ВНИМАНИЕ: теряются функции, Date, undefined, etc

// Лучше - используйте проверенные библиотеки
import { cloneDeep } from 'lodash';
const safeCopy = cloneDeep(original);

Immutability библиотеки

// Immer - самая популярная
import produce from 'immer';

const state = { user: { name: "John" } };
const newState = produce(state, draft => {
  draft.user.name = "Jane"; // можно мутировать draft
});
// Вернёт новый объект если что-то изменилось

// Использование в React
setUser(produce(user => {
  user.name = "Jane";
  user.age = 31;
}));

Правила для безопасного кода

// 1. Не мутируй props
function Button({ disabled, onClick }: Props) {
  disabled = false; // ПЛОХО - не повлияет, но плохая практика
  return <button disabled={disabled} />
}

// 2. Не мутируй state напрямую
const [count, setCount] = useState(0);
count = 5; // ПЛОХО

// 3. При работе с массивами в state используй новые массивы
setItems([...items, newItem]); // ХОРОШО

// 4. Для сложных объектов используй immer
setUser(produce(draft => {
  draft.profile.name = "Jane";
}));

// 5. Если нужна мутация - копируй перед ней
const arr = [1, 2, 3];
const sorted = [...arr].sort(); // копируем, потом мутируем

Итоговый принцип

В современном JavaScript и React - избегайте мутаций state и props. Это главное правило для надёжного и предсказуемого кода. Мутирующие методы нужны только для локальных переменных или новых объектов до их использования.

Что такое тег link в HTML? | PrepBro