Другое

String.slice против String.substring: ключевые различия

Узнайте ключевые различия между методами String.slice() и String.substring() в JavaScript. Узнайте, как они по-разному обрабатывают отрицательные индексы, порядок параметров и крайние случаи. Выберите подходящий метод для вашего кода.

В чём разница между String.slice и String.substring в JavaScript?

Основное различие между String.slice() и String.substring() в JavaScript заключается в том, как они обрабатывают отрицательные индексы и крайние случаи. String.slice() рассматривает отрицательные индексы как отсчет с конца строки, в то время как String.substring() рассматривает их как 0. Кроме того, slice() соответствует современному спецификации JavaScript, в то время как substring() имеет устаревшее поведение, которое может приводить к неожиданным результатам при определенных комбинациях параметров.

Содержание

Базовый синтаксис и параметры

У обоих методов String.slice() и String.substring() одинаковый базовый синтаксис:

javascript
// Базовый синтаксис для обоих методов
str.slice(startIndex, endIndex)
str.substring(startIndex, endIndex)

Оба метода извлекают часть строки и возвращают ее как новую строку. Параметры работают следующим образом:

  • startIndex: Позиция, откуда начинается извлечение (включительно)
  • endIndex: Позиция, где заканчивается извлечение (не включая)
  • Если endIndex опущен, извлечение продолжается до конца строки

Ключевое сходство: Оба метода являются неразрушающими - они не изменяют исходную строку, а возвращают новую строку, содержащую извлеченную часть.

Обработка отрицательных индексов

Здесь находится наиболее существенное различие между двумя методами:

String.slice():

  • Принимает отрицательные индексы и рассматривает их как отсчет с конца строки
  • Отрицательный индекс эквивалентен string.length + negativeIndex
  • Возвращает пустую строку, если вычисленный начальный индекс больше конечного индекса

String.substring():

  • Преобразует отрицательные индексы в 0
  • Не отсчитывает с конца строки
  • Может приводить к неожиданным результатам при отрицательных значениях
javascript
const str = "Hello, World!";

// slice с отрицательными индексами
console.log(str.slice(-6, -1)); // "World" (эквивалентно str.slice(7, 11))
console.log(str.slice(-1));     // "!" (последний символ)

// substring с отрицательными индексами
console.log(str.substring(-6, -1)); // "Hello, W" (отрицательные индексы становятся 0)
console.log(str.substring(-1));     // "Hello, World!" (отрицательный индекс становится 0)

Порядок параметров и крайние случаи

Еще одно важное различие заключается в том, как эти методы обрабатывают переставленные или недопустимые параметры:

String.slice():

  • Возвращает пустую строку, если начальный индекс больше или равен конечному индексу
  • Строго следует спецификации и предсказуемо

String.substring():

  • Автоматически меняет параметры местами, если start > end
  • Рассматривает индексы вне диапазона как 0 или string.length
  • Такое поведение может приводить к неожиданным результатам
javascript
const str = "JavaScript";

// slice с переставленными параметрами
console.log(str.slice(5, 2));   // "" (пустая строка)
console.log(str.slice(10, 15)); // "" (пустая строка)

// substring с переставленными параметрами
console.log(str.substring(5, 2));   // "av" (переставлено на substr(2, 5))
console.log(str.substring(10, 15)); // "" (начальный индекс рассматривается как string.length)

Последовательность возвращаемых значений

Оба метода возвращают новую строку, но их поведение в крайних случаях различается:

Последовательное поведение с slice():

  • Всегда следует одной и той же логической схеме
  • Отрицательные индексы отсчитываются с конца
  • Возвращает пустую строку для недопустимых диапазонов
  • Более предсказуемо и современно

Непоследовательное поведение с substring():

  • Перестановка параметров может запутать
  • Отрицательные индексы рассматриваются как 0
  • Устаревшее поведение, не соответствующее соглашениям JavaScript

Вопросы производительности

Что касается производительности, оба метода в современных JavaScript-движках в целом эквивалентны. Однако есть некоторые соображения:

  • slice() часто предпочтителен в современном коде для последовательности
  • substring() может иметь незначительные преимущества производительности в очень специфических крайних случаях в старых движках
  • Разница в производительности незначительна в большинстве реальных приложений

Использование памяти идентично для обоих методов, поскольку они оба создают новые строки.

Когда использовать каждый метод

Используйте String.slice() когда:

  • Вам нужно современное, предсказуемое поведение
  • Работа с отрицательными индексами
  • Следование соглашениям JavaScript (похоже на Array.slice)
  • Написание чистого, поддерживаемого кода

Используйте String.substring() когда:

  • Работа со старыми кодовыми базами
  • Вам специально нужно поведение перестановки параметров
  • Работа с очень старыми браузерами или средами
  • Когда вы уверены в значениях параметров

Современные лучшие практики JavaScript в общем рекомендуют использовать slice() за его последовательность и предсказуемое поведение.

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

Вот практические примеры, демонстрирующие различия:

javascript
const text = "Programming is fun";

// Извлечение последнего слова с помощью slice
const lastWordSlice = text.slice(text.lastIndexOf(' ') + 1);
console.log(lastWordSlice); // "fun"

// Извлечение последнего слова с помощью substring (более сложный)
const lastWordSubstring = text.substring(text.lastIndexOf(' ') + 1);
console.log(lastWordSubstring); // "fun"

// Извлечение средних символов
const middleSlice = text.slice(5, 15);
console.log(middleSlice); // "ramming is f"

const middleSubstring = text.substring(5, 15);
console.log(middleSubstring); // "ramming is f"

// Работа с отрицательными индексами безопасно
const safeSlice = text.slice(-3); // "fun"
const safeSubstring = text.substring(text.length - 3); // "fun"

Практическое применение - извлечение пути URL:

javascript
const url = "/users/123/profile/posts/456";

// Извлечение ID пользователя с помощью slice (чистый подход)
const userIdSlice = url.slice(7, 10);
console.log(userIdSlice); // "123"

// Извлечение ID поста с помощью substring (требует расчета длины)
const postIdSubstring = url.substring(29, 32);
console.log(postIdSubstring); // "456"

Заключение

Ключевые различия между String.slice() и String.substring() являются фундаментальными для понимания манипуляции строками в JavaScript:

  1. Обработка отрицательных индексов: slice() правильно обрабатывает отрицательные индексы, отсчитывая с конца, в то время как substring() рассматривает их как 0
  2. Перестановка параметров: slice() возвращает пустую строку для недопустимых диапазонов, в то время как substring() автоматически переставляет параметры
  3. Современный vs Устаревший: slice() следует современным соглашениям JavaScript, в то время как substring() сохраняет устаревшее поведение
  4. Предсказуемость: slice() более предсказуем и последователен в разных случаях использования

Для современного JavaScript-разработки String.slice() в общем является предпочтительным выбором благодаря своей последовательности и соответствию соглашениям JavaScript. Однако понимание обоих методов важно при работе со старым кодом или в специфических случаях использования, где перестановка параметров substring() может быть полезной.


Источники

  1. MDN Web Docs - String.prototype.slice()
  2. MDN Web Docs - String.prototype.substring()
  3. ECMAScript Language Specification - String.prototype.slice()
  4. ECMAScript Language Specification - String.prototype.substring()
Авторы
Проверено модерацией
Модерация