This post outlines all the ways we can check if a string starts with or ends
with another string, also in case insensitive way. In ECMAScript 6 Harmony there
will be startsWith and endsWith methods. Here’s how to use those and how to
polyfill it.
Native ES6 methods startsWith() and endsWith()
Syntax:
str.startsWith(searchString[, position])Here’s an example of how to check if a string stats with a hash, which is ideal
use of startsWith because it’s case sensitive only, and hash doesn’t have a
case:
'#something'.startsWith('#') // true
'#something'.startsWith('🤡') // falseUsing the second, position, param you can tell the method the position to
start the search from:
'#something'.startsWith('t', 5) // trueThe endsWith() works exactly the same, with one difference: the second
parameter, which is length rather than position. The length defaults to the
string’s length str.length.
Tell it that the string ends after the underscore:
'foo_bar'.endsWith('_', 4) // trueThe well supported lastIndexOf method
Syntax:
str.lastIndexOf(searchValue[, fromIndex])The lastIndexOf method is supported more widely than startsWith or
endsWith, if that happens to be important to you. It returns the position of
the last occurrence of the string being searched:
'foo bar baz'.lastIndexOf('bar') // 4
'foo bar baz'.lastIndexOf('z') // 10It can be used to check the first character:
if ('#foo'.lastIndexOf('#') === 0) {
console.log('Yup')
}And the last character:
const str = '#fooz'
if (str.lastIndexOf('z', str.length - 1) === str.length - 1) {
console.log('Ends in z')
}Do the checking with regex
Syntax:
RegExp.test(string)We can use the test() RegExp method here. The cool thing about regex is that
the match can be case insensitive, if you’re not in control of the input, or
something.
Here’s starts with:
const regex = /^f/i
regex.test('FOO') // true
regex.test('foo') // trueAnd ends with:
const regex = /z$/i
regex.test('FOOZ') // true
regex.test('fooz') // trueThe "official" startsWith and endsWith polyfill
This is taken from the MDN article, it uses the same underlying technique, but it also takes the position parameter:
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
enumerable: false,
configurable: false,
writable: false,
value: function (searchString, position) {
position = position || 0
return this.lastIndexOf(searchString, position) === position
},
})
}And the same for endsWith from the corresponding
MDN article:
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
var subjectString = this.toString()
if (position === undefined || position > subjectString.length) {
position = subjectString.length
}
position -= searchString.length
var lastIndex = subjectString.indexOf(searchString, position)
return lastIndex !== -1 && lastIndex === position
}
}