The most efficient way to check the last character of a string with JavaScript

Josh Sherman
3 min read
Software Development JavaScript

Recently I was writing some code that needed to detect if a certain character was at the end of the string to determine if some additional logic should be executed.

The reason for this was because the additional logic to run was pretty hefty and for pre-mature optimization’s sake, I didn’t want it to execute every damn time.

This resulted in me writing a quick str.slice(-1) to grab the last character. As of late I have been favoring using str.slice() for this because the syntax is nice and clean:

if (someString.slice(-1) === 'Z') {
  console.log('Zee end is Z');

Looks great, does what I need it to, next issue.

But since I was already being mindful of not always running the less performant code, I got to wondering how good the aforementioned str.slice() actually was.

To test things out, I headed over to [][jsperf] and setup a handful of test cases to see how my go to of str.slice() stacked up against some other ways to grab the last character of a string.

Here’s the other approaches I came up with:

// length - 1
someString[someString.length - 1] === 'Z';
someString.substr(someString.length - 1) === 'Z';
someString.substring(someString.length - 1) === 'Z';

// --length
someString[--someString.length] === 'Z';
someString.substr(--someString.length) === 'Z';
someString.substring(--someString.length) === 'Z';

// Good ol' RegExp

// New stuff I wasn't even aware of

As you may have expected, the regular expression approach was one of the slowest of the bunch, but was beat out by the new school approach of using str.endsWith().

What was quite surprising to me was that using --str.length actually performed horribly in comparison to the str.length - 1 equivalents, but also came in as the last performant overall.

So which approach is the most efficient?

Sadly [for me], it wasn’t my precious str.slice(-1). Using str.slice() clocked in around the same as both str.substr(str.length - 1) and str.substring(str.length - 1) with str[str.length - 1] the clear winner consistently winning and clocking in between ±0.8% and ±1.1%.

These results make sense though, generally speaking, in most programming languages the use of functions, built-in or user defined, there is some additional overhead in comparison to not using a function.

By referencing the string’s index and using str.length we’re completely avoiding any overhead from using functions but I also believe the length of a string is stored as part of the string’s prototype and not necessarily calculated on the fly.

If you’re interested in running these tests on your own system, you can check them out [over on][tests].

jsperf: tests:

Join the Conversation

Good stuff? Want more?

Weekly emails about technology, development, and sometimes sauerkraut.

100% Fresh, Grade A Content, Never Spam.

Related Articles