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

Как работает Replace?

2.0 Middle🔥 122 комментариев
#JavaScript Core

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

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

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

Как работает replace в JavaScript и браузере

Replace — это фундаментальный метод, который работает в нескольких контекстах: строки (replace), история браузера (history.replace), маршруты (navigate). Рассмотрим все варианты и их различия.

1. String.replace() — замена в строках

Базовое использование

// Замена первого вхождения
const text = 'Hello World, Hello JavaScript';
const result = text.replace('Hello', 'Hi');
console.log(result); // 'Hi World, Hello JavaScript'

// Первое вхождение заменяется, остальные остаются
// Оригинальная строка не меняется (строки неизменяемы)

Замена всех вхождений

// С регулярным выражением и флагом g (global)
const text = 'Hello World, Hello JavaScript';
const result = text.replace(/Hello/g, 'Hi');
console.log(result); // 'Hi World, Hi JavaScript'

// Или используя replaceAll
const result2 = text.replaceAll('Hello', 'Hi');
console.log(result2); // 'Hi World, Hi JavaScript'

Replace с регулярными выражениями

// Замена по паттерну
const email = 'user@example.com';
const masked = email.replace(/(.{2})(.*)(@.*)/, '$1***$3');
console.log(masked); // 'us***@example.com'

// Replace с функцией
const text = 'I have 2 apples and 5 oranges';
const result = text.replace(/\d+/g, (match) => {
  return parseInt(match) * 2;
});
console.log(result); // 'I have 4 apples and 10 oranges'

Replace с функцией обратного вызова

// Функция получает информацию о каждом совпадении
const text = 'The price is $100 and $200';
const result = text.replace(/\$(\d+)/g, (match, price, offset, string) => {
  // match: '$100' (полное совпадение)
  // price: '100' (первая группа)
  // offset: 13 (позиция в строке)
  // string: вся исходная строка
  
  return `$${parseInt(price) * 0.9.toFixed(2)}`; // Скидка 10%
});
console.log(result); // 'The price is $90 and $180'

2. history.replace() — замена в истории браузера

Отличие от history.push()

// push — добавляет в историю (можно вернуться кнопкой Back)
history.pushState({ page: 1 }, 'Page 1', '/page1');
history.pushState({ page: 2 }, 'Page 2', '/page2');
// Кнопка Back вернёт на /page1

// replace — заменяет текущую запись в истории
history.replaceState({ page: 1 }, 'Page 1', '/page1');
history.replaceState({ page: 2 }, 'Page 2', '/page2');
// Кнопка Back вернёт ТО, ЧТО БЫЛО ДО /page1

Практические примеры

// 1. Обновить URL без добавления в историю
const updateFilters = (filters) => {
  const query = new URLSearchParams(filters).toString();
  history.replaceState(null, '', `?${query}`);
  // Пользователь видит новый URL, но история не изменяется
};

// 2. Скрыть временные URL
const login = async () => {
  // Показываем промежуточный URL
  history.pushState(null, '', '/login?redirecting');
  
  // После входа заменяем историю
  const user = await authenticateUser();
  history.replaceState({ user }, '', '/dashboard');
  // Теперь Back ведёт не на /login?redirecting, а на главную
};

// 3. Обновить язык без истории
const changeLanguage = (lang) => {
  const currentPath = window.location.pathname.replace(/^\/[a-z]{2}/, '');
  const newPath = `/${lang}${currentPath}`;
  history.replaceState(null, '', newPath);
};

3. Router.replace() — в React Router

Различие navigate vs replace

import { useNavigate } from 'react-router-dom';

function LoginComponent() {
  const navigate = useNavigate();
  
  const handleLogin = async () => {
    // navigate('/dashboard'); // Добавляет в историю
    navigate('/dashboard', { replace: true }); // Заменяет историю
  };
  
  return <button onClick={handleLogin}>Login</button>;
}

// После входа кнопка Back вернёт не на страницу входа
// а на ту, откуда пришли пользователь

При обработке ошибок

function ProtectedRoute() {
  const { user, isLoading } = useAuth();
  const navigate = useNavigate();
  
  if (isLoading) return <div>Loading...</div>;
  
  // Если пользователь не авторизован, заменяем историю на /login
  if (!user) {
    navigate('/login', { replace: true });
    return null;
  }
  
  return <Dashboard />;
}

// Важно: replace: true чтобы пользователь не мог вернуться
// на защищённую страницу нажимом Back

4. window.location.replace() — замена в окне браузера

// Полностью заменяет текущую страницу в истории
window.location.replace('https://example.com');
// Пользователь не может вернуться на предыдущую страницу

// Различие от assign
window.location.assign('https://example.com'); // Добавляет в историю
window.location.replace('https://example.com'); // Заменяет

Сравнение всех replace

// 1. String replace — работает со строками
const newString = 'hello'.replace('h', 'H'); // 'Hello'

// 2. history.replaceState — работает с историей браузера
history.replaceState(state, title, url);
// Меняет текущую запись в истории

// 3. navigate(..., { replace: true }) — в React Router
navigat('/path', { replace: true });
// Заменяет историю перехода маршрутов

// 4. window.location.replace() — полная замена страницы
window.location.replace('/new-page');
// Не добавляет в историю, заменяет текущую запись

Практические примеры для фронтенда

1. Форма входа

function LoginForm() {
  const navigate = useNavigate();
  const [credentials, setCredentials] = React.useState({});
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    try {
      const user = await loginAPI(credentials);
      // После входа заменяем историю, чтобы нельзя было вернуться
      navigate('/dashboard', { replace: true });
    } catch (error) {
      console.log('Login failed');
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input 
        value={credentials.email}
        onChange={(e) => setCredentials({...credentials, email: e.target.value})}
      />
      <button type="submit">Login</button>
    </form>
  );
}

2. Фильтры без добавления истории

function ProductList() {
  const [filters, setFilters] = React.useState({});
  
  const handleFilterChange = (newFilters) => {
    setFilters(newFilters);
    
    // Обновляем URL, но не добавляем в историю
    const query = new URLSearchParams(newFilters).toString();
    window.history.replaceState(null, '', `?${query}`);
  };
  
  return (
    <div>
      <Filters onChange={handleFilterChange} />
      <Products filters={filters} />
    </div>
  );
}

3. Редирект при ошибке

function ProtectedPage() {
  const { user, isLoading } = useAuth();
  const navigate = useNavigate();
  
  React.useEffect(() => {
    if (!isLoading && !user) {
      // Редирект без добавления в историю
      navigate('/login', { replace: true });
    }
  }, [user, isLoading, navigate]);
  
  if (isLoading) return <Loading />;
  if (!user) return null;
  
  return <Content />;
}

4. Замена текста в поиске

function SearchBox() {
  const [query, setQuery] = React.useState('');
  
  const handleSearch = (term) => {
    // Нормализуем поисковый запрос
    const normalized = term.toLowerCase().trim();
    const cleaned = normalized.replace(/[^a-z0-9\s]/g, '');
    
    setQuery(cleaned);
  };
  
  return (
    <input
      value={query}
      onChange={(e) => handleSearch(e.target.value)}
      placeholder="Search..."
    />
  );
}

Когда использовать replace

Используй replace когда:

  1. Перенаправляем неавторизованного пользователя → не даём вернуться на защищённую страницу
  2. Меняем фильтры → URL обновляется, но история браузера не нужна
  3. После действия (успешно заполненная форма) → не даём вернуться к незаполненной форме
  4. Смена языка/темы → просто обновляем URL

Не используй replace когда:

  1. Переход по ссылкам → используй обычный переход
  2. Навигация между разделами → пользователь должен вернуться
  3. Поиск результатов → пользователь может захотеть вернуться

Вывод

Replace работает по-разному в разных контекстах:

  • String.replace() — замена подстроки в строке
  • history.replaceState() — замена в истории браузера
  • navigate(..., { replace: true }) — замена в маршрутах
  • window.location.replace() — полная замена страницы

Главное различие: replace НЕ добавляет в историю браузера, а ЗАМЕНЯЕТ текущую запись. Это полезно для редиректов, фильтров и защиты от нежелательных возвратов.

Как работает Replace? | PrepBro