Explain Codes LogoExplain Codes Logo

Endswith in JavaScript

javascript
endswith
performance
regex
Anton ShumikhinbyAnton Shumikhin·Aug 5, 2024
TLDR

To verify if a str ends with a specific substring, use the str.endsWith(substring) ES6 function:

const result = 'Hello, world!'.endsWith('world!'); // output: true

Pre-ES6 survival guide

Not everyone lives in an ES6 world. Older JavaScript versions may lack support for endsWith. In such scenarios, a typeof implementation check before using endsWith can prevent surprises:

if (typeof String.prototype.endsWith !== 'function') { // Can you believe this?! We don't have endsWith, Time to make our own version! String.prototype.endsWith = function(suffix) { return this.indexOf(suffix, this.length - suffix.length) !== -1; }; }

Diving deeper: Beyond basics

Regex to the rescue: endsWith alternative

If you can't use endsWith or must handle complex patterns, regular expressions are your friends:

const endsWithHash = /#$/; // Checks if string ends with a hashtag, just like your Instagram caption. const result = endsWithHash.test('Page Title #'); // output: true

Performance matters: Substring methods vs charAt

Whilst it's tempting to use substr and slice methods, they could incur overhead by creating unnecessary substrings. In contrast, char comparison using string length avoids this overhead:

const str = 'Happy coding!'; const endsWithExclamation = (str, char) => str.charAt(str.length - 1) === char; const result = endsWithExclamation(str, '!'); // output: true

DIY: Custom endsWith

Sometimes built-in functions can't satisfy your needs. Crafting a customized endsWith function, packaged as a standalone function, might be your solution—and it won't meddle with native prototypes:

function customEndsWith(str, search) { // Insert your custom logic here. Go wild! return str.substring(str.length - search.length) === search; }

Case sensitivity and regex

By default, regular expressions are case-sensitive. For case-insensitive endsWith, use the i flag:

const caseInsensitiveEndsWith = /happy$/i; const result = caseInsensitiveEndsWith.test('Be Happy'); // output: true

Exploring the edges and corners

Age is just a number: Handling environments sans ES6

If you have to deal with legacy environments or outdated browsers that lack endsWith, you can either use polyfills – MDN provides handy ones – or you can craft functions that simulate endsWith:

if (!String.prototype.endsWith) { // Woah, where are we? The land before time? String.prototype.endsWith = function(search, this_len) { if (this_len === undefined || this_len > this.length) { this_len = this.length; } return this.substring(this_len - search.length, this_len) === search; }; }

Speed is the game: Performance-critical applications

For apps dealing with sizable strings or requiring responsive interactions, direct character comparison can deliver results faster than the substring approach:

const endsWithChar = (str, char) => str.charAt(str.length - 1) === char; // Sorry substr, but we don't need you here.

I've got multiple choices: Dealing with multiple endings

For scenarios where you might need to check against a multitude of possible endings, a custom function accepting an array of endings simplifies things:

const endsWithMultiples = (str, endings) => endings.some(ending => str.endsWith(ending)); const result = endsWithMultiples('file.txt', ['pdf', 'doc', 'txt']); // pdf and doc are out, txt gets the prize!