1741

How would I write the equivalent of C#'s String.StartsWith in JavaScript?

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

haystack.startsWith(needle) == true

Note: This is an old question, and as pointed out in the comments ECMAScript 2015 (ES6) introduced the .startsWith method. However, at the time of writing this update (2015) browser support is far from complete.

Luca Kiebel
  • 8,292
  • 5
  • 24
  • 37

19 Answers19

1809

You can use ECMAScript 6's String.prototype.startsWith() method, but it's not yet supported in all browsers. You'll want to use a shim/polyfill to add it on browsers that don't support it. Creating an implementation that complies with all the details laid out in the spec is a little complicated. If you want a faithful shim, use either:

Once you've shimmed the method (or if you're only supporting browsers and JavaScript engines that already have it), you can use it like this:

   console.log("Hello World!".startsWith("He")); // true
    
var haystack = "Hello world";
var prefix = 'orl';
console.log(haystack.startsWith(prefix)); // false
Ran Marciano
  • 1,254
  • 5
  • 7
  • 25
Christian C. Salvadó
  • 723,813
  • 173
  • 899
  • 828
  • 1
    WARNING! These jsperf tests don't work in browsers that are good at JIT compiling. Browsers like Firefox and Chrome **sometimes recognize it when the result of an operation is discarded, and therefore don't perform the operation**. Apart from that, modern javascript engines use **branch prediction**, so the test strings should be different in each iteration. – Aloso Sep 19 '17 at 21:04
  • note: if typescript is complaining when trying to build your project, you at least need to have "es2015.core" in the lib array of your tsconfig.json – baywet Mar 28 '19 at 18:57
1300

Another alternative with .lastIndexOf:

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

This looks backwards through haystack for an occurrence of needle starting from index 0 of haystack. In other words, it only checks if haystack starts with needle.

In principle, this should have performance advantages over some other approaches:

  • It doesn't search the entire haystack.
  • It doesn't create a new temporary string and then immediately discard it.
Mark Amery
  • 110,735
  • 57
  • 354
  • 402
Mark Byers
  • 719,658
  • 164
  • 1,497
  • 1,412
  • 1
    Not sure which case @rfcoder89 is taking about - https://jsfiddle.net/jkzjw3w2/1/ – Gulfaraz Rahman May 20 '16 at 11:15
  • 5
    @rfcoder89 Notice the second parameter of lastIndexOf: `"aba".lastIndexOf ("a")` is 2 as you point out, but `"aba".lastIndexOf ("a", 0)` is 0, which is correct – maxpolk May 20 '16 at 14:37
  • 1
    Thank you so much. String.startsWith does not work on Android lollipop WebView, but this lastIndexOf snippet does!!! – Hermandroid Dec 06 '16 at 23:22
  • with **lastIndexOf** the string is searched from the end to the beginning so it searches the whole string: so its inefficiency grows for very long strings to search in. – willy wonka Apr 08 '17 at 00:18
  • 8
    @willywonka No, it's not if you have 0 startIndex, it is searched from 0 pos and it's the only check. The whole string is searched only if fromIndex >= str.length. – greene May 19 '17 at 08:27
  • @greene How could `haystack.lastIndexOf(needle, 0)` not end up searching the whole string if the needle is not in there? It would have to keep searching until it reached the beginning right? I think if you don't have access to `endsWith`, the fastest alternative is probably `substring`: `function endsWith(haystack, needle){ return haystack.substring(haystack.length - needle.length) === needle; }` – Stijn de Witt May 16 '20 at 12:54
  • Mmm I'm making a fool of myself. You are talking about `startsWith`, not `endsWith`... – Stijn de Witt May 16 '20 at 12:56
595
data.substring(0, input.length) === input
gblazex
  • 45,901
  • 12
  • 91
  • 86
cobbal
  • 66,343
  • 18
  • 135
  • 154
  • 3
    @ANeves I suspect it strongly depends on the browser and the data used. See Ben Weaver's answer for actual measurements. On the browser I'm running currently (Chrome 12.0.742 on Windows) substring wins for success and prepared regex wins for failure. – cobbal Jul 14 '11 at 17:11
  • 4
    @cobbal Maybe. But `.lastIndexOf(input, 0)` compares the first N chars, whereas `.substring(0, input.length) === input` counts N, substrings the data to N length, and then compares those N chars. Unless there is code optimization, this second version cannot be faster than the other. Don't get me wrong though, I would never find by myself something better than you suggested. :) – ANeves thinks SE is evil Jul 18 '11 at 09:19
  • 2
    @ANeves But .lastIndexOf on a long string that's going to return false is going to iterate over the entire string (O(N)), whereas the .substring case iterates over a potentially much smaller string. If you expect majority successes or only small inputs, .lastIndexOf is likely faster - otherwise .substring is likely faster. .substring also risks an exception if the input is longer than the string being checked. – Chris Moschini Jan 22 '13 at 20:18
  • 14
    @ChrisMoschini, don't forget that Mark Byers' solution has `lastIndexOf` start at index 0, not the end. That tripped me up, too, initially. Still, checking what a string starts with is such a common task that JavaScript really ought to have a proper API for it, not all the idioms and alternatives you see on this page, however clever they are. – Randall Cook Jan 29 '13 at 20:58
  • 5
    I prefer cobbal's solution over Mark's. Even if mark's is faster, and an impressive trick using the params, it's very difficult to read compared to substring. – ThinkBonobo Feb 13 '15 at 23:17
  • IMO - Mark's is more readable and easier to understand you are doing a "startsWith" test. This solution while tricky is difficult to grasp what is going on? I actually like momomo's better and it is the one I use. – Neal Davis Jun 06 '19 at 23:49
185

Without a helper function, just using regex's .test method:

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

To do this with a dynamic string rather than a hardcoded one (assuming that the string will not contain any regexp control characters):

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

You should check out Is there a RegExp.escape function in Javascript? if the possibility exists that regexp control characters appear in the string.

Community
  • 1
  • 1
Vincent
  • 2,884
  • 1
  • 16
  • 21
68

Best solution:

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

And here is endsWith if you need that too:

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

For those that prefer to prototype it into 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;
});

Usage:

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

With method:

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
mmm
  • 18,431
  • 26
  • 99
  • 165
  • I think you've mixed up lastIndexOf and indexOf in your functions - startsWith should be return str.indexOf(word, 0) === 0; – Richard Matheson Jan 12 '17 at 14:51
  • 5
    @RichardMatheson the problem with using indexOf is that if it fails matching at the start, it will continue searching the entire string, whereby lastIndexOf starts from the length of the word and walks back to zero. Got it? – mmm Jan 27 '17 at 08:48
  • 2
    Ahh yes makes sense now - i didn't pay attention to the indices you were using. Very nice trick! – Richard Matheson Feb 05 '17 at 10:54
55

I just wanted to add my opinion about this.

I think we can just use like this:

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

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}
Mr.D
  • 5,765
  • 8
  • 41
  • 95
  • 2
    The Mark Byers answer was compared for performance of three different correct approaches by @relfor. This correct approach was not favored because it requires searching the entire string. – maxpolk May 20 '16 at 15:24
  • @maxpolk I think `indexOf` will stop searching entire string when it finds first occurence. I have checked it. – Mr.D May 21 '16 at 03:30
  • 8
    If the first occurrence is not found at the very beginning, this approach begins to grow inefficient the longer it continues looking for it, potentially searching until it reaches the very end, instead of giving up much earlier. Because there is a potential for inefficiency, it is not favored among the three correct approaches. – maxpolk Jun 27 '16 at 21:04
  • 2
    @Mr.D And if there is no match? – mmm Sep 16 '16 at 09:58
  • else when all of the haystack has been searched? is better: http://stackoverflow.com/a/36876507/961018 .. only searches up to word length – mmm Sep 16 '16 at 10:57
  • You also might want to cast the input as String, just in case, or it won't have the indexOf operator: (String(haystack)).indexOf(needle) – eyal_katz Jun 22 '19 at 22:55
40

Here is a minor improvement to CMS's solution:

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

Checking whether the function already exists in case a future browser implements it in native code or if it is implemented by another library. For example, the Prototype Library implements this function already.

Using ! is slightly faster and more concise than === 0 though not as readable.

Kit
  • 15,260
  • 3
  • 47
  • 87
  • 1
    This could become a problem: If the implementation already in place behaves differently from my own this would break my application. – Christoph Wurm Jul 12 '11 at 09:20
  • 2
    This has the O(N) problem discussed here http://stackoverflow.com/questions/646628/javascript-startswith/646631#comment20370021_646631 – Chris Moschini Jan 30 '13 at 07:52
  • 1
    using ! there is very messy – JonnyRaa Feb 06 '15 at 12:52
  • -1; adding this to `String.prototype` is a bad idea because it doesn't come anywhere close to complying with the [spec](http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.startswith) for `String.prototype.startsWith`. Any code that tries to use the ES6 method is liable to fail if you're doing this; it may well look to see if the method is already defined, see that it is (badly, by you) and not add in a spec-compliant shim, leading to incorrect behaviour later. – Mark Amery Nov 05 '15 at 23:23
21

Also check out underscore.string.js. It comes with a bunch of useful string testing and manipulation methods, including a startsWith method. From the docs:

startsWith _.startsWith(string, starts)

This method checks whether string starts with starts.

_("image.gif").startsWith("image")
=> true
Mark Amery
  • 110,735
  • 57
  • 354
  • 402
studgeek
  • 12,579
  • 6
  • 78
  • 90
15

I recently asked myself the same question.
There are multiple possible solutions, here are 3 valid ones:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0 (added after seeing Mark Byers's answer)
  • using a loop:

    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;
    }
    

I haven't come across the last solution which makes uses of a loop.
Surprisingly this solution outperforms the first 3 by a significant margin.
Here is the jsperf test I performed to reach this conclusion: http://jsperf.com/startswith2/2

Peace

ps: ecmascript 6 (harmony) introduces a native startsWith method for strings.
Just think how much time would have been saved if they had thought of including this much needed method in the initial version itself.

Update

As Steve pointed out (the first comment on this answer), the above custom function will throw an error if the given prefix is shorter than the whole string. He has fixed that and added a loop optimization which can be viewed at http://jsperf.com/startswith2/4.

Note that there are 2 loop optimizations which Steve included, the first of the two showed better performance, thus I will post that code below:

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;
}
Community
  • 1
  • 1
Raj Nathani
  • 2,705
  • 1
  • 18
  • 19
  • See the latest rev. Besides the bug in the above version (it will throw if the string is shorter than the prefix), it's also slower than a more optimized version. See http://jsperf.com/startswith2/4 and http://jsperf.com/js-startswith/35. – Steve Hollasch Jul 15 '14 at 01:35
  • ^Thanks for pointing out the case where the string is shorter than prefix – Raj Nathani Oct 29 '14 at 18:06
  • http://jsperf.com/startswith2/29 => startsWith5 is concise and perform really well =) – gtournie Nov 17 '15 at 07:52
11

Since this is so popular I think it is worth pointing out that there is an implementation for this method in ECMA 6 and in preparation for that one should use the 'official' polyfill in order to prevent future problems and tears.

Luckily the experts at Mozilla provide us with one:

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;
    };
}

Please note that this has the advantage of getting gracefully ignored on transition to ECMA 6.

miln
  • 135
  • 6
Scheintod
  • 7,352
  • 7
  • 35
  • 58
5

The best performant solution is to stop using library calls and just recognize that you're working with two arrays. A hand-rolled implementation is both short and also faster than every other solution I've seen here.

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;
}

For performance comparisons (success and failure), see http://jsperf.com/startswith2/4. (Make sure you check for later versions that may have trumped mine.)

Mark Amery
  • 110,735
  • 57
  • 354
  • 402
Steve Hollasch
  • 1,664
  • 1
  • 15
  • 17
2

I just learned about this string library:

http://stringjs.com/

Include the js file and then use the S variable like this:

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

It can also be used in NodeJS by installing it:

npm install string

Then requiring it as the S variable:

var S = require('string');

The web page also has links to alternate string libraries, if this one doesn't take your fancy.

Ashley Davis
  • 9,255
  • 7
  • 58
  • 79
2
  1. The question is a bit old, but I wanted to write this answer to show you some benchmarks I made based on all the answers provided here and the jsperf shared by Jim Buck.

I basically needed a fast way to find if a long needle is within a long haystack and they are very similar except for the last characters.

Here's the code I have written which for each function (splice, substring, startsWith, etc.) tests both when they return false and true against a haystack string (nestedString) of 1.000.0001 characters and a falsy or truthy needle string of 1.000.000 chars (testParentStringFalse and testParentStringTrue, respectively):

// 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)
}

I runned this benchmark test on Chrome 75, Firefox 67, Safari 12 and Opera 62.

I haven't included Edge and IE because I do not have them on this machine, but if someone of you wants to run the script against Edge and at least IE 9 and share the output here I would be very curious to see the results.

Just remember that you need to recreate the 3 long strings and save the script in a file which you then open in your browser as copy/paste on the browser's console will block it as each string's length is >= 1.000.000).

Here are the outputs:

Chrome 75 (substring wins):

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 wins):

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 wins for false results, startsWith wins for true results, also Safari is the fastest in terms of total time to to execute the whole test):

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 wins. Results are similar to Chrome and I am not surprised as Opera is based on Chromium and 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}

It turns out every browser has its own implementation details (apart Opera, which is based on Chrome's Chromium and Blink).

Of course, further test with different use cases could and should be performed (e.g. when needle is really short compared to haystack, when haystack is shorter than needle, etc...), but in my case I needed to compare very long strings and wanted to share it here.

tonix
  • 5,862
  • 10
  • 61
  • 119
1
var str = 'hol';
var data = 'hola mundo';
if (data.length >= str.length && data.substring(0, str.length) == str)
    return true;
else
    return false;
Peter O.
  • 28,965
  • 14
  • 72
  • 87
Chris
  • 1,183
  • 1
  • 7
  • 4
0

Based on the answers here, this is the version I am now using, as it seems to give the best performance based on JSPerf testing (and is functionally complete as far as I can tell).

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;
    }
}

This was based on startsWith2 from here: http://jsperf.com/startswith2/6. I added a small tweak for a tiny performance improvement, and have since also added a check for the comparison string being null or undefined, and converted it to add to the String prototype using the technique in CMS's answer.

Note that this implementation doesn't support the "position" parameter which is mentioned in this Mozilla Developer Network page, but that doesn't seem to be part of the ECMAScript proposal anyway.

0

I am not sure for javascript but in typescript i did something like

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

I guess it should work on js too. I hope it helps!

0

The string object has methods like startsWith, endsWith and includes methods.

  • StartsWith checks whether the given string starts at the beginning or not.

  • endsWith checks whether the given string is at the end or not.

  • includes checks whether the given string is present at any part or not.

You can find the complete difference between these three in the bellow youtube video

https://www.youtube.com/watch?v=E-hyeSwg0PA

-2

If you are working with startsWith() and endsWith() then you have to be careful about leading spaces. Here is a complete example:

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
  • 6,510
  • 7
  • 31
  • 52
  • 3
    This is very non-standard behavior: the string " abc" does NOT start with "abc". More specifically, ECMA 6 does not assume any sort of string trimming, so that whitespace must match exactly to yield a startsWith match. – Steve Hollasch Jul 15 '14 at 02:01
  • 3
    What... how is this answering the question? – DCShannon Oct 21 '15 at 01:05
  • 1
    @DCShannon it isn't. It's incomprehensible nonsense. – Mark Amery Nov 05 '15 at 01:19
  • 2
    @SteveHollasch My intention was to aware anyone looking for same issue I faced. That we needs to be careful with leading spaces when working with `startsWith()` and `endsWith()` functions. Nothing else! – immayankmodi Nov 05 '15 at 12:27
-3

You can also return all members of an array that start with a string by creating your own prototype / extension to the the array prototype, aka

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;
};

And to use it:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Nepaluz
  • 614
  • 1
  • 10
  • 24