How would I write the equivalent of C#\'s String.StartsWith in JavaScript?
var haystack = \'hello world\';
var needle = \'he\';
haystack.startsWith(needle)
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;
}
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:
String.prototype.startsWith
.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:
"Hello World!".startsWith("He"); // true
var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
data.substring(0, input.length) === input
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
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.
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.