НейроАгент

Как проверить, начинается ли строка с определенной подстроки в JavaScript

Узнайте, как проверить, начинается ли строка с другой строки в JavaScript с помощью современного метода startsWith() и альтернативных подходов для старых браузеров. Полное руководство с примерами и полифилами.

Вопрос

Как проверить, начинается ли строка с другой строки в JavaScript?

Как написать аналог метода C# String.StartsWith в JavaScript?

Пример:

javascript
var haystack = 'hello world';
var needle = 'he';

haystack.startsWith(needle) == true

Примечание: Это старый вопрос, и, как указано в комментариях, ECMAScript 2015 (ES6) представил метод .startsWith. Однако на момент написания этого обновления (2015) поддержка браузерами была далеко не полной.

НейроАгент

Современный способ проверки, начинается ли строка с другой строки в JavaScript

Современный способ проверки, начинается ли одна строка с другой в JavaScript, — использование метода String.prototype.startsWith(), введенного в ECMAScript 2015 (ES6). Этот метод возвращает true, если строка начинается с указанных символов, и false в противном случае. Для старых браузеров, которые не поддерживают ES6, можно использовать полифилы или альтернативные подходы, такие как сравнения с использованием indexOf() или substr().

Содержание

Использование современного метода startsWith()

Метод startsWith() является наиболее элегантным и читаемым решением для проверки, начинается ли строка с другой строки. Он является частью спецификации ES6 и предоставляет чистый, интуитивный API.

Базовый синтаксис

javascript
string.startsWith(searchString[, position])
  • searchString: Символы, которые нужно найти в начале строки
  • position: Необязательный. Позиция в этой строке, с которой начинается поиск searchString; по умолчанию 0

Примеры

javascript
const str = 'Hello World';

// Базовое использование
console.log(str.startsWith('Hello')); // true
console.log(str.startsWith('World')); // false

// Использование параметра position
console.log(str.startsWith('World', 6)); // true (ищет с индекса 6)
console.log(str.startsWith('lo', 3)); // true (ищет с индекса 3)

Чувствительность к регистру

Метод startsWith() чувствителен к регистру:

javascript
const str = 'Hello World';
console.log(str.startsWith('hello')); // false
console.log(str.startsWith('Hello')); // true

Особые случаи

javascript
const str = 'Hello World';

// Пустая строка всегда возвращает true
console.log(str.startsWith('')); // true

// Строка короче искомой строки
console.log(str.startsWith('Hello World!')); // false

Совместимость с браузерами и полифилы

Хотя startsWith() поддерживается во всех современных браузерах, более старые браузеры, такие как Internet Explorer 11, не поддерживают его нативно. Вот несколько подходов для обеспечения совместимости:

1. Обнаружение возможностей и полифил

javascript
if (!String.prototype.startsWith) {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.substr(position, searchString.length) === searchString;
  };
}

2. Надежный полифил от Mathias Bynens

Для более комплексного решения, которое точно соответствует спецификации ES6, можно использовать полифил Mathias Bynens, доступный на GitHub:

javascript
// From: https://github.com/mathiasbynens/String.prototype.startsWith
if (!String.prototype.startsWith) {
  (function() {
    'use strict'; // необходимо для поддержки `apply`/`call` с `undefined`/`null`
    var defineProperty = (function() {
      try {
        var o = {};
        var func = Object.defineProperty;
        return func(o, o, o) && func;
      } catch (e) {
        /* IE 8 имеет сломанный Object.defineProperty */
      }
    }());
    var toString = {}.toString;
    var startsWith = ''[startsWith];
    if (
      defineProperty &&
      toString.call(startsWith) === '[object Function]'
    ) {
      defineProperty(String.prototype, 'startsWith', {
        value: startsWith,
        configurable: true,
        writable: true
      });
    } else {
      String.prototype.startsWith = startsWith;
    }
  })();
}

3. Использование библиотеки Core-js

Для более надежного решения, включающего многие возможности ES6, используйте библиотеку core-js:

javascript
import 'core-js/features/string/starts-with';

Или в браузере:

html
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.12/core.min.js"></script>

Альтернативные методы для старых браузеров

До ES6 разработчики использовали различные подходы для достижения той же функциональности:

1. Использование indexOf()

javascript
function startsWith(haystack, needle) {
  return haystack.indexOf(needle) === 0;
}

// Использование
var haystack = 'hello world';
var needle = 'he';
console.log(startsWith(haystack, needle)); // true

2. Использование substr()

javascript
function startsWith(haystack, needle) {
  return haystack.substr(0, needle.length) === needle;
}

// Использование
var haystack = 'hello world';
var needle = 'he';
console.log(startsWith(haystack, needle)); // true

3. Использование substring()

javascript
function startsWith(haystack, needle) {
  return haystack.substring(0, needle.length) === needle;
}

// Использование
var haystack = 'hello world';
var needle = 'he';
console.log(startsWith(haystack, needle)); // true

4. Использование slice()

javascript
function startsWith(haystack, needle) {
  return haystack.slice(0, needle.length) === needle;
}

// Использование
var haystack = 'hello world';
var needle = 'he';
console.log(startsWith(haystack, needle)); // true

Практические примеры и случаи использования

Валидация URL

javascript
function isValidUrl(url) {
  return url.startsWith('http://') || url.startsWith('https://');
}

console.log(isValidUrl('https://example.com')); // true
console.log(isValidUrl('ftp://example.com')); // false

Проверка расширения файла

javascript
function isImageFile(filename) {
  return filename.startsWith('.jpg') || filename.startsWith('.png') || 
         filename.startsWith('.gif') || filename.startsWith('.bmp');
}

console.log(isImageFile('image.jpg')); // true
console.log(isImageFile('document.pdf')); // false

Валидация пути маршрута

javascript
function isSecureRoute(path) {
  return path.startsWith('/admin') || path.startsWith('/dashboard') || 
         path.startsWith('/api/private');
}

console.log(isSecureRoute('/admin/users')); // true
console.log(isSecureRoute('/public/home')); // false

Сопоставление префикса с позицией

javascript
function hasProtocol(url) {
  return url.startsWith('http://', 0) || url.startsWith('https://', 0);
}

function hasProtocolAt(url, position) {
  return url.startsWith('http://', position) || url.startsWith('https://', position);
}

console.log(hasProtocol('https://example.com')); // true
console.log(hasProtocol('ftp://example.com')); // false
console.log(hasProtocolAt('Check: https://example.com', 7)); // true

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

При выборе между разными методами учитывайте производительность:

Сравнение производительности

Согласно документации MDN, нативный метод startsWith() обычно является наиболее эффективным. Альтернативные реализации можно сравнить следующим образом:

javascript
// Настройка теста производительности
function testPerformance() {
  const str = 'Hello World, this is a test string for performance';
  const prefix = 'Hello World';
  const iterations = 100000;

  // Тест startsWith()
  console.time('startsWith');
  for (let i = 0; i < iterations; i++) {
    str.startsWith(prefix);
  }
  console.timeEnd('startsWith');

  // Тест indexOf()
  console.time('indexOf');
  for (let i = 0; i < iterations; i++) {
    str.indexOf(prefix) === 0;
  }
  console.timeEnd('indexOf');

  // Тест substr()
  console.time('substr');
  for (let i = 0; i < iterations; i++) {
    str.substr(0, prefix.length) === prefix;
  }
  console.timeEnd('substr');
}

Рейтинг производительности

Как правило, рейтинг производительности от самого быстрого к самому медленному:

  1. startsWith() (нативная реализация)
  2. indexOf() === 0
  3. Сравнение substr()
  4. Сравнение substring()
  5. Сравнение slice()

Полное решение с резервным вариантом

Для решения, готового к использованию в производстве и работающего во всех браузерах, вот комплексный подход:

1. Современный подход с обнаружением возможностей

javascript
// Проверяем, доступен ли startsWith, если нет, используем полифил
if (!String.prototype.startsWith) {
  // Простой полифил
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.substr(position, searchString.length) === searchString;
  };
}

// Использование
var haystack = 'hello world';
var needle = 'he';
console.log(haystack.startsWith(needle)); // true

2. Подход на основе библиотек

javascript
// Использование lodash/underscore
_.startsWith(haystack, needle);

// Или использование пользовательской функции утилиты
function safeStartsWith(str, search, position) {
  if (String.prototype.startsWith) {
    return str.startsWith(search, position);
  } else {
    position = position || 0;
    return str.substr(position, search.length) === search;
  }
}

3. Интеграция с инструментами сборки

Если вы используете инструмент сборки, такой как Webpack, вы можете автоматически включать полифилы:

javascript
// webpack.config.js
module.exports = {
  // ... другая конфигурация
  entry: ['core-js/fn/string/starts-with', './app.js']
};

4. Подход с прогрессивным улучшением

javascript
// Определяем startsWith, если он недоступен
if (typeof String.prototype.startsWith !== 'function') {
  String.prototype.startsWith = function(searchString, position) {
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}

// Теперь вы можете использовать его везде
var url = 'https://example.com/path';
if (url.startsWith('https://')) {
  // Обработка безопасного соединения
}

Источники

  1. String.prototype.startsWith() - JavaScript | MDN
  2. How to check if a string “StartsWith” another string? - Stack Overflow
  3. JavaScript - How to Check if a String “StartsWith” Another String in JavaScript? - GeeksforGeeks
  4. String startsWith() Method in JavaScript - Medium
  5. How to check if a string starts with another in JavaScript - Flavio Copes
  6. GitHub - mathiasbynens/String.prototype.startsWith
  7. Add startsWith in IE 11 - Stack Overflow
  8. Polyfills and Browser Compatibility - DEV Community

Заключение

Проверка того, начинается ли одна строки с другой в JavaScript, является простой задачей с использованием современного метода startsWith(), введенного в ES6. Для наиболее читаемого и поддерживаемого кода всегда предпочитайте нативный метод startsWith(), когда ваша целевая аудитория использует современные браузеры. Для максимальной совместимости со всеми браузерами, включая более старые, такие как Internet Explorer 11, реализуйте соответствующий полифил или используйте обнаружение возможностей для предоставления резервной функциональности. Альтернативные подходы с использованием indexOf(), substr(), substring() или slice() могут использоваться, когда поддержка ES6 недоступна, хотя они могут быть немного менее производительными, чем нативная реализация. Всегда тщательно тестируйте логику префиксации строк в целевой браузерной среде, чтобы обеспечить согласованное поведение.