Как проверить, является ли строка «StartsWith» другой строкой?

1690

Как бы я написал эквивалент C # String.StartsWithв JavaScript?

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

haystack.startsWith(needle) == true

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

Лука Кибель
источник

Ответы:

1773

Вы можете использовать String.prototype.startsWith()метод ECMAScript 6 , но он пока не поддерживается во всех браузерах . Вы захотите использовать shim / polyfill, чтобы добавить его в браузеры, которые его не поддерживают. Создание реализации, которая соответствует всем деталям, изложенным в спецификации, немного сложнее. Если вам нужна верная прокладка, используйте либо:

После того, как вы изменили метод (или если вы поддерживаете только браузеры и механизмы JavaScript, у которых он уже есть), вы можете использовать его следующим образом:

"Hello World!".startsWith("He"); // true

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
CMS
источник
@gtournie, почему запускается с одним из худших методов для проверки, если строка начинается со строки? (см. ваш комментарий здесь: stackoverflow.com/questions/646628/… ) вы с большим энтузиазмом относитесь к сравнению символов на символ. Я надеюсь, что компиляторы достаточно умны, чтобы НЕ генерировать строку для каждой строки [индекс], потому что, если вы просто напишите это: )
Мартин Шеффер
@MartijnScheffer: ответ был отредактирован много раз, так как я ответил, и теперь совершенно другой (я удалил свой комментарий;). Я согласен, что метод startWith в ECMAScript 6 - лучший способ сделать это.
gtournie
6
@GrahamLaight, когда вы говорите, что поддерживается IE, вероятно, вы подразумеваете под Edge. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Маркус
@Marcus, извиняюсь, если я ошибся - моя информация пришла от: w3schools.com/jsref/jsref_startswith.asp
Грэм Лайт
ПРЕДУПРЕЖДЕНИЕ! Эти jsperf-тесты не работают в браузерах, которые хороши в JIT-компиляции. Браузеры, такие как Firefox и Chrome, иногда распознают его, когда результат операции отбрасывается, и поэтому не выполняют операцию . Кроме того, современные механизмы javascript используют предсказание ветвлений , поэтому тестовые строки должны быть разными на каждой итерации.
Aloso
1283

Еще одна альтернатива с .lastIndexOf:

haystack.lastIndexOf(needle, 0) === 0

Это смотрит назад через haystackдля возникновения , needleначиная с индекса 0в haystack. Другими словами, он только проверяет, haystackначинается ли с needle.

В принципе, это должно иметь преимущества в производительности по сравнению с некоторыми другими подходами:

  • Он не ищет весь haystack .
  • Он не создает новую временную строку, а затем немедленно удаляет ее.
Марк Байерс
источник
1
Не уверен, о каком случае @ rfcoder89 идет речь - jsfiddle.net/jkzjw3w2/1
Гульфараз Рахман
5
@ rfcoder89 Обратите внимание на второй параметр lastIndexOf: "aba".lastIndexOf ("a")2, как вы "aba".lastIndexOf ("a", 0)
указали
1
Огромное спасибо. String.startsWith не работает на Android lollipop WebView, но этот последний фрагмент кода работает !!!
Герман
с помощью lastIndexOf строка ищется от конца к началу, поэтому она ищет всю строку: поэтому ее неэффективность возрастает для очень длинных строк для поиска.
willy wonka
8
@willywonka Нет, это не так, если у вас 0 startIndex, поиск выполняется с 0 позиций, и это единственная проверка. Вся строка ищется только если fromIndex> = str.length.
Greene
588
data.substring(0, input.length) === input
cobbal
источник
3
@ ANeves Я подозреваю, что это сильно зависит от браузера и используемых данных. См. Ответ Бена Уивера для реальных измерений. В браузере, в котором я сейчас работаю (Chrome 12.0.742 для Windows), подстрока выигрывает для успеха и готовит регулярные выражения для неудачи.
коббал
4
@cobbal Возможно. Но .lastIndexOf(input, 0)сравнивает первые N символов, тогда как .substring(0, input.length) === inputсчитает N, подстрокует данные с длиной N, а затем сравнивает эти N символов. Если нет оптимизации кода, эта вторая версия не может быть быстрее, чем другая. Не поймите меня неправильно, я никогда не найду ничего лучше, чем вы предлагаете. :)
ANEves
2
@ANeves Но .lastIndexOf для длинной строки, которая будет возвращать false, будет выполнять итерацию по всей строке (O (N)), тогда как случай .substring выполняет итерацию по потенциально намного меньшей строке. Если вы ожидаете большинства успехов или только небольших входных данных, .lastIndexOf, вероятно, быстрее, в противном случае .substring, вероятно, быстрее. .substring также рискует исключение, если ввод длиннее проверяемой строки.
Крис Москини
14
@ChrisMoschini, не забывайте, что решение Марка Байерса lastIndexOfначинается с индекса 0, а не с конца. Это поначалу меня тоже сбило с толку. Тем не менее, проверка того, с чего начинается строка, является настолько распространенной задачей, что JavaScript действительно должен иметь соответствующий API, а не все идиомы и альтернативы, которые вы видите на этой странице, какими бы умными они ни были.
Рэндалл Кук
4
Я предпочитаю решение Коббала, а не Марка. Даже если метка быстрее и впечатляющий трюк с использованием параметров, ее очень трудно прочитать по сравнению с подстрокой.
ThinkBonobo
184

Без вспомогательной функции, просто с помощью .testметода регулярных выражений :

/^He/.test('Hello world')

Чтобы сделать это с динамической строкой, а не жестко закодированной (при условии, что строка не будет содержать никаких управляющих символов регулярного выражения):

new RegExp('^' + needle).test(haystack)

Вы должны проверить Есть ли функция RegExp.escape в Javascript? если существует возможность, что управляющие символы регулярного выражения появляются в строке.

Винсент
источник
1
Чтобы сделать выражение чувствительным к регистру, используйте/^he/i
kaizer1v
64

Лучшее решение:

function startsWith(str, word) {
    return str.lastIndexOf(word, 0) === 0;
}

И вот что заканчивается, если вам это тоже нужно:

function endsWith(str, word) {
    return str.indexOf(word, str.length - word.length) !== -1;
}

Для тех, кто предпочитает создавать прототип в String:

String.prototype.startsWith || (String.prototype.startsWith = function(word) {
    return this.lastIndexOf(word, 0) === 0;
});

String.prototype.endsWith   || (String.prototype.endsWith = function(word) {
    return this.indexOf(word, this.length - word.length) !== -1;
});

Применение:

"abc".startsWith("ab")
true
"c".ensdWith("c") 
true

С методом:

startsWith("aaa", "a")
true
startsWith("aaa", "ab")
false
startsWith("abc", "abc")
true
startsWith("abc", "c")
false
startsWith("abc", "a")
true
startsWith("abc", "ba")
false
startsWith("abc", "ab")
true
ммм
источник
Я думаю, что вы смешали lastIndexOf и indexOf в своих функциях - старты должны возвращать str.indexOf (word, 0) === 0;
Ричард Мэтисон
5
@RichardMatheson проблема с использованием indexOf заключается в том, что если ему не удастся сопоставить в начале, он продолжит поиск всей строки, в результате чего lastIndexOf начинается с длины слова и возвращается к нулю. Понял?
ммм
2
Ах, да, это имеет смысл сейчас - я не обращал внимания на индексы, которые вы использовали. Очень хороший трюк!
Ричард Мэтсон
54

Я просто хотел добавить свое мнение по этому поводу.

Я думаю, что мы можем просто использовать так:

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

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}
Mr.D
источник
2
Ответ Mark Byers был сравнен с @relfor для выполнения трех разных правильных подходов. Этот правильный подход не был одобрен, потому что он требует поиска по всей строке.
maxpolk
@maxpolk Я думаю, indexOfчто перестанет искать всю строку, когда она найдет первый случай. Я проверил это.
Mr.D
8
Если первое вхождение не найдено в самом начале, этот подход начинает становиться неэффективным, чем дольше он продолжает его искать, потенциально ищет, пока не достигнет самого конца, вместо того, чтобы сдаться намного раньше. Поскольку существует потенциал неэффективности, он не является предпочтительным среди трех правильных подходов.
maxpolk
2
@ Mr.D А если нет совпадений?
ммм
еще когда весь стог сена был обыскан? лучше: stackoverflow.com/a/36876507/961018 .. ищет только до длины слова
ммм
39

Вот небольшое улучшение решения CMS:

if(!String.prototype.startsWith){
    String.prototype.startsWith = function (str) {
        return !this.indexOf(str);
    }
}

"Hello World!".startsWith("He"); // true

 var data = "Hello world";
 var input = 'He';
 data.startsWith(input); // true

Проверка, существует ли функция в случае, если будущий браузер реализует ее в собственном коде или если она будет реализована другой библиотекой. Например, библиотека прототипов уже реализует эту функцию.

Использование !немного быстрее и лаконичнее, чем === 0при чтении.

Комплект
источник
1
Это может стать проблемой: если уже реализованная реализация ведет себя не так, как у меня, это повредит моему приложению.
Кристоф Вурм
2
Это имеет проблему O (N), обсуждаемую здесь stackoverflow.com/questions/646628/javascript-startswith/…
Крис Москини
1
с помощью ! там очень грязно
JonnyRaa
-1; добавлять это к String.prototypeплохой идее, потому что это не подходит близко к соответствию спецификации для String.prototype.startsWith. Любой код, который пытается использовать метод ES6, может потерпеть неудачу, если вы делаете это; он может хорошо посмотреть, если метод уже определен, увидеть, что он (плохо) вами, и не добавить совместимую со спецификацией прокладку, что впоследствии приведет к некорректному поведению.
Марк Амери
21

Также проверьте underscore.string.js . Он поставляется с кучей полезных методов тестирования и манипуляции со строками, включая startsWithметод. Из документов:

начинается с _.startsWith(string, starts)

Этот метод проверяет, stringначинается ли с starts.

_("image.gif").startsWith("image")
=> true
studgeek
источник
1
Мне нужно_.string.startsWith
полковник Паник
15

Я недавно задал себе тот же вопрос.
Есть несколько возможных решений, вот 3 из них:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(добавлено после просмотра ответа Марка Байерса )
  • используя цикл:

    function startsWith(s,starter) {
      for (var i = 0,cur_c; i < starter.length; i++) {
        cur_c = starter[i];
        if (s[i] !== starter[i]) {
          return false;
        }
      }
      return true;
    }

Я не сталкивался с последним решением, которое использует цикл.
Удивительно, но это решение значительно превосходит первые 3.
Вот тест jsperf, который я выполнил, чтобы прийти к такому выводу: http://jsperf.com/startswith2/2

мир

PS: ecmascript 6 (гармония) представляет нативный startsWithметод для строк.
Подумайте, сколько времени было бы сэкономлено, если бы они решили включить этот столь необходимый метод в саму первоначальную версию.

Обновить

Как указал Стив (первый комментарий к этому ответу), вышеуказанная пользовательская функция выдаст ошибку, если данный префикс короче всей строки. Он исправил это и добавил оптимизацию цикла, которую можно посмотреть по адресу http://jsperf.com/startswith2/4 .

Обратите внимание, что есть 2 цикла оптимизации, которые включил Стив, первый из двух показал лучшую производительность, поэтому я опубликую этот код ниже:

function startsWith2(str, prefix) {
  if (str.length < prefix.length)
    return false;
  for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
    continue;
  return i < 0;
}
Радж Натани
источник
Смотрите последнюю версию Помимо ошибки в вышеупомянутой версии (она будет выдавать, если строка короче префикса), она также медленнее, чем более оптимизированная версия. См. Jsperf.com/startswith2/4 и jsperf.com/js-startswith/35 .
Стив Холлаш
^ Спасибо за указание на случай, когда строка короче префикса
Радж Натани
jsperf.com/startswith2/29 => старты с 5 лаконичны и работают очень хорошо =)
gtournie
11

Поскольку это настолько популярно, я думаю, что стоит отметить, что в ECMA 6 есть реализация этого метода, и при подготовке к этому следует использовать «официальный» полифилл, чтобы предотвратить будущие проблемы и разрывы.

К счастью, специалисты Mozilla предоставляют нам один:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

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

Пожалуйста, обратите внимание, что это имеет то преимущество, что изящно игнорируется при переходе на ECMA 6.

Scheintod
источник
5

Лучшее решение - перестать использовать библиотечные вызовы и просто признать, что вы работаете с двумя массивами. Ручная реализация является как короткой, так и более быстрой, чем любое другое решение, которое я видел здесь.

function startsWith2(str, prefix) {
    if (str.length < prefix.length)
        return false;
    for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
        continue;
    return i < 0;
}

Для сравнения производительности (успех и неудача), см. Http://jsperf.com/startswith2/4 . (Убедитесь, что вы проверите более поздние версии, которые могли превзойти мою.)

Стив Холлаш
источник
2

Я только что узнал об этой библиотеке строк:

http://stringjs.com/

Включите файл js, а затем используйте Sпеременную следующим образом:

S('hi there').endsWith('hi there')

Его также можно использовать в NodeJS, установив его:

npm install string

Затем требуя его в качестве Sпеременной:

var S = require('string');

На веб-странице также есть ссылки на библиотеки альтернативных строк, если вам не по вкусу.

Эшли Дэвис
источник
2
  1. Вопрос немного старый, но я хотел написать этот ответ, чтобы показать вам некоторые тесты, которые я сделал, основываясь на всех ответах, представленных здесь, и на jsperf, предоставленном Джимом Баком.

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

Вот код, который я написал, который для каждой функции (сращивания, подстроки, startWith и т. Д.) Проверяет оба значения, когда они возвращают значение false и true для строки haystack ( nestedString) из 1.000.0001 символов и ложной или истинной строки иглы 1.000.000 символы ( testParentStringFalseи testParentStringTrue, соответственно):

// nestedString is made of 1.000.001 '1' repeated characters.
var nestedString = '...'

// testParentStringFalse is made of 1.000.000 characters,
// all characters are repeated '1', but the last one is '2',
// so for this string the test should return false.
var testParentStringFalse = '...'

// testParentStringTrue is made of 1.000.000 '1' repeated characters,
// so for this string the test should return true.
var testParentStringTrue = '...'

// You can make these very long strings by running the following bash command
// and edit each one as needed in your editor
// (NOTE: on OS X, `pbcopy` copies the string to the clipboard buffer,
//        on Linux, you would probably need to replace it with `xclip`):
// 
//     printf '1%.0s' {1..1000000} | pbcopy
// 

function testString() {
    let dateStart
    let dateEnd
    let avg
    let count = 100000
    const falseResults = []
    const trueResults = []

    /* slice */
    console.log('========> slice')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== slice')
    console.log('')
    /* slice END */

    /* lastIndexOf */
    console.log('========> lastIndexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringFalse, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringTrue, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== lastIndexOf')
    console.log('')
    /* lastIndexOf END */

    /* indexOf */
    console.log('========> indexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringFalse) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringTrue) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== indexOf')
    console.log('')
    /* indexOf END */

    /* substring */
    console.log('========> substring')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== substring')
    console.log('')
    /* substring END */

    /* startsWith */
    console.log('========> startsWith')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringFalse)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringTrue)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== startsWith')
    console.log('')
    /* startsWith END */

    falseResults.sort((a, b) => a.avg - b.avg)
    trueResults.sort((a, b) => a.avg - b.avg)

    console.log('false results from fastest to slowest avg:', falseResults)
    console.log('true results from fastest to slowest avg:', trueResults)
}

Я провел этот тест на Chrome 75 , Firefox 67 , Safari 12 и Opera 62 .

Я не включил Edge и IE, потому что у меня их нет на этой машине, но если кто-то из вас захочет запустить скрипт для Edge и хотя бы IE 9 и поделиться выводом здесь, мне было бы очень любопытно увидеть результаты.

Просто помните, что вам нужно воссоздать 3 длинные строки и сохранить скрипт в файле, который вы затем откроете в браузере, поскольку копирование / вставка на консоли браузера заблокирует его, поскольку длина каждой строки> = 1.000.000).

Вот результаты:

Хром 75 ( substringпобед):

false results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08271}
2)  {"label":"slice","avg":0.08615}
3)  {"label":"lastIndexOf","avg":0.77025}
4)  {"label":"indexOf","avg":1.64375}
5)  {"label":"startsWith","avg":3.5454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08213}
2)  {"label":"slice","avg":0.08342}
3)  {"label":"lastIndexOf","avg":0.7831}
4)  {"label":"indexOf","avg":0.88988}
5)  {"label":"startsWith","avg":3.55448}

Firefox 67 ( indexOfпобед):

false results from fastest to slowest avg
1)  {"label":"indexOf","avg":0.1807}
2)  {"label":"startsWith","avg":0.74621}
3)  {"label":"substring","avg":0.74898}
4)  {"label":"slice","avg":0.78584}
5)  {"label":"lastIndexOf","avg":0.79668}

true results from fastest to slowest avg:
1)  {"label":"indexOf","avg":0.09528}
2)  {"label":"substring","avg":0.75468}
3)  {"label":"startsWith","avg":0.76717}
4)  {"label":"slice","avg":0.77222}
5)  {"label":"lastIndexOf","avg":0.80527}

Safari 12 ( sliceпобеждает за ложные результаты, startsWithпобеждает за истинные результаты, также Safari является самым быстрым с точки зрения общего времени для выполнения всего теста):

false results from fastest to slowest avg:
1) "{\"label\":\"slice\",\"avg\":0.0362}"
2) "{\"label\":\"startsWith\",\"avg\":0.1141}"
3) "{\"label\":\"lastIndexOf\",\"avg\":0.11512}"
4) "{\"label\":\"substring\",\"avg\":0.14751}"
5) "{\"label\":\"indexOf\",\"avg\":0.23109}"

true results from fastest to slowest avg:
1) "{\"label\":\"startsWith\",\"avg\":0.11207}"
2) "{\"label\":\"lastIndexOf\",\"avg\":0.12196}"
3) "{\"label\":\"substring\",\"avg\":0.12495}"
4) "{\"label\":\"indexOf\",\"avg\":0.33667}"
5) "{\"label\":\"slice\",\"avg\":0.49923}"

Opera 62 ( substringвыигрывает. Результаты похожи на Chrome, и я не удивлен, поскольку Opera основана на Chromium и Blink):

false results from fastest to slowest avg:
{"label":"substring","avg":0.09321}
{"label":"slice","avg":0.09463}
{"label":"lastIndexOf","avg":0.95347}
{"label":"indexOf","avg":1.6337}
{"label":"startsWith","avg":3.61454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08855}
2)  {"label":"slice","avg":0.12227}
3)  {"label":"indexOf","avg":0.79914}
4)  {"label":"lastIndexOf","avg":1.05086}
5)  {"label":"startsWith","avg":3.70808}

Оказывается, у каждого браузера есть свои особенности реализации (кроме Opera, основанной на Chrome Chromium и Blink).

Конечно, можно и нужно проводить дальнейшее тестирование с различными вариантами использования (например, когда игла действительно короткая по сравнению со стогом сена, когда стог сена короче иглы и т. Д.), Но в моем случае мне нужно было сравнить очень длинные струны и хотел бы поделиться этим здесь.

Tonix
источник
1
var str = 'hol';
var data = 'hola mundo';
if (data.length >= str.length && data.substring(0, str.length) == str)
    return true;
else
    return false;
Крис
источник
0

Основываясь на ответах здесь, это версия, которую я сейчас использую, поскольку она, кажется, дает лучшую производительность, основанную на тестировании JSPerf (и насколько я могу судить, функционально завершена).

if(typeof String.prototype.startsWith != 'function'){
    String.prototype.startsWith = function(str){
        if(str == null) return false;
        var i = str.length;
        if(this.length < i) return false;
        for(--i; (i >= 0) && (this[i] === str[i]); --i) continue;
        return i < 0;
    }
}

Это было основано на StartWith2 отсюда: http://jsperf.com/startswith2/6 . Я добавил небольшой твик для незначительного улучшения производительности, а также добавил проверку на то, что строка сравнения имеет значение null или undefined, и преобразовал ее для добавления в прототип String, используя технику ответа CMS.

Обратите внимание, что эта реализация не поддерживает параметр «position», который упоминается на этой странице в сети разработчиков Mozilla , но в любом случае он не является частью предложения ECMAScript.

Эдвард Миллен
источник
0

Я не уверен, для JavaScript, но в машинописи я сделал что-то вроде

var str = "something";
(<String>str).startsWith("some");

Я думаю, это должно работать на JS тоже. Я надеюсь, что это помогает!

Андреас Хаджитома
источник
-2

Если вы работаете с, startsWith()а endsWith()затем вы должны быть осторожны с ведущими пробелами. Вот полный пример:

var str1 = " Your String Value Here.!! "; // Starts & ends with spaces    
if (str1.startsWith("Your")) { }  // returns FALSE due to the leading spaces…
if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces…

var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`.
if (str2.startsWith("Your")) { }  // returns TRUE
if (str2.endsWith("Here.!!")) { } // returns TRUE
immayankmodi
источник
3
Это очень нестандартное поведение: строка «abc» НЕ начинается с «abc». В частности, ECMA 6 не предполагает какого-либо обрезания строки, поэтому пробельные символы должны точно совпадать, чтобы получить совпадение StartWith.
Стив Холлаш
3
Что ... как это отвечает на вопрос?
DCShannon
1
@DCShannon это не так. Это непонятная ерунда.
Марк Амери
2
@ SteveHollasch Я хотел знать, что кто-то ищет ту же проблему, с которой я столкнулся. То, что мы нужно быть осторожным с начальными пробелами при работе с startsWith()и endsWith()функции. Ничего больше!
immayankmodi
-3

Вы также можете вернуть все члены массива, которые начинаются со строки, создав собственный прототип / расширение для прототипа массива, иначе

Array.prototype.mySearch = function (target) {
    if (typeof String.prototype.startsWith != 'function') {
        String.prototype.startsWith = function (str){
        return this.slice(0, str.length) == str;
      };
    }
    var retValues = [];
    for (var i = 0; i < this.length; i++) {
        if (this[i].startsWith(target)) { retValues.push(this[i]); }
    }
    return retValues;
};

И использовать это:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Nepaluz
источник