Course: JavaScript

Progress (0%)

JavaScript String Methods

Chapter 20 32 mins

Learning outcomes:

  1. Changing casing using toLowerCase() and toUpperCase()
  2. Trimming whitespace using trim(), trimStart(), and trimEnd()
  3. Searching using indexOf() and lastIndexOf()
  4. Splitting a string using split()
  5. Slicing a string using slice() and substring()
  6. Replacing substrings using replace() and replaceAll()

Introduction

Just how common it is to use strings in programming is it to process them. For instance one may want to find the total number of characters in a string, or slice a certain part of it, or replace certain occurrences in it from a given substring, or convert the string to uppercase characters and much more.

JavaScript provides developers with a solid handful of string methods to aid in processing strings for different purposes. In this chapter we will go over some of the most useful of these methods and how exactly to use them.

So why are we waiting here?

Changing casing

JavaScript provides us with two string methods to change the casing of a string to either all lowercase characters or all uppercase characters.

They are toLowerCase() and toUpperCase(), respectively.

string.toLowerCase()
string.toUpperCase()

Both require no arguments at all — just call them and let the casing be changed.

Consider the snippet below:

'Hello World!'.toLowerCase()
'hello world'
'Hello World!'.toUpperCase()
'HELLO WORLD!'

In the first statement, we get the lowercased version of the string 'Hello World!' returned which is 'hello world!', while in the second one, we get the uppercased version returned, which is 'HELLO WORLD!'.

It's quite common to use toLowerCase() (or toUpperCase()) when comparing strings.

For instance, when comparing two strings together for equality, where the casing of the characters doesn't matter, we would first convert both of them to lowercase (or uppercase) and then perform the comparison.

An example follows:

var str = 'JavaScript';
var lang = prompt();

if (lang.toLowerCase() === str.toLowerCase()) {
   console.log('You know JavaScript');
}

Here we create a string str and then a variable lang which is assigned the value input in a prompt dialog. In this prompt, the user could enter the text 'JavaScript' in any casing, like 'JavaSCRIPT', 'JAVASCRIPT' etc; they'll all compare equal to 'JavaScript'.

Our program would convert both the input value and the string str into lowercase before comparing them to make sure that the casing doesn't interfere with our comparison.

This could be thought of as normalizing the casing of the two given strings before comparing them.

Of course, if we want to strictly compare two strings together without being lenient in the casing of characters, we don't need to be using toLowerCase().

Trimming whitespace characters

Often times while working with user input, you'll come across strings with redundant pieces of whitespace characters at the beginning or end.

Whitespace characters include spaces, tabs (\t), carriage returns (\r) and newlines (\n).

For instance, a user might have input a value containing extra spaces at the start, or there might be unnecessary newlines at the end.

To clear away such characters from the string, we could use the trim() string method.

The trim() method removes whitespace characters from both ends of a given string.

Here's its syntax:

string.trim()

As with the casing methods discussed above, trim() doesn't take any argument — call it as is and let the magic happen!

Shown below are a couple of examples:

'   Hello World!   '.trim()
'Hello World!'
'\n   Hello World!\n\n'.trim()
'Hello World!'

In the first statement, trim() removes all the spaces from both ends of the string. In the second statement, trim() removes both spaces and newline sequences from both ends of the string.

If we wish to remove whitespace characters from only one end of a string, we could use the more specific methods, trimStart() and trimEnd().

Both the methods work exactly like trim(), except for that,

trimStart() operates only on the start of a string and trimEnd() operates only on the end of a string.

Shown below are a couple of examples.

First, let's see trimStart():

'   Hello World!   '.trimStart()
'Hello World! '
'\n   Hello World!\n\n'.trimStart()
'Hello World!\n\n'

And now for trimEnd():

'   Hello World!   '.trimEnd()
' Hello World!'
'\n   Hello World!\n\n'.trimEnd()
'\n Hello World!'

Easy, isn't this?

There are two alias methods in JavaScript for trimStart() and trimEnd(). That is, they are the same methods with just different names. They are trimLeft() and trimRight(), respectively.

Searching for substrings

Searching for stuff within strings is more than just a common activity in programming. In JavaScript, there are mainly two string methods that could be used in this regard.

They are indexOf() and lastIndexOf().

The indexOf() method returns the index of the first occurrence of a given substring within a main string. If the substring isn't found, -1 is returned.

Here's the syntax of indexOf():

string.indexOf(substring[, index])

substring is the string to be searched for in string whereas index is the position where to begin the searching. By default, index is set to 0 — the beginning of the string.

If substring is found in string, its index is returned, or else the value -1.

Consider the code below:

var str = 'Hello World!';
console.log(str.indexOf('World'));
6

We search for 'World' in str using indexOf(). What's returned is 6 which is where the substring 'World' begins in str ('Hello World!').

Let's consider another example.

var str = 'Hello World!';
console.log(str.indexOf('o'));
4

Here we're trying to search for the character 'o' inside str and get 4 returned. This is because indexOf() is only concerned with the first match.

The second parameter of indexOf() is handy when we want to search again, beyond the index of the first occurrence of a substring.

In the code below we demonstrate this idea:

var str = 'Hello';

var i = str.indexOf('l');
console.log(i);

i = str.indexOf('l', i + 1);
console.log(i);

console.log(str.indexOf('l', i + 1));
2
3
-1

To start off, we retrieve the index of the first occurrence of 'l' in str. This gives us 2 (the index of the highlighted character in 'Hello World!')

Next, we retrieve the index of the next occurrence of 'l' in str by providing a second argument to indexOf(), 1 greater than the index of the last occurrence of 'l'. This gives us 3 (i.e. the index of the highlighted character in 'Hello World!').

After this, once again, we retrieve the index of the next occurrence of 'l' in str beyond the last index. Since, 'l' doesn't occur anymore in str, this gives us -1.

Create a function getAllIndexes() that takes in two strings str and substr, and outputs back an array containing the index of each occurrence of substr in str, or otherwise the value -1.

Shown below is an illustration of how should the function work:

getAllIndexes('Hello World!', 'l')
[2, 3, 9]
getAllIndexes('Hello World!', 'd')
[10]
getAllIndexes('Hello World!', 'i')
-1
function getAllIndexes(str, substr) {
   var i = str.indexOf(substr);

   if (i === -1) return -1;

   var indexes = [];
   while (i !== -1) {
      indexes.push(i);
      i = str.indexOf(substr, i + 1);
   }
   return indexes;
}

Splitting strings

A string could be broken down into an array of substrings using the split() method.

The split() method splits a string apart at every occurrence of a given separator, and returns back an array containing the leftover substrings.

The syntax is as follows:

string.split([separator[, limit]])
  • separator specifies the separator at which to break the main string apart. If omitted, split() returns an array containing the whole string.
  • limit specifies the maximum number of elements in the returned array. If omitted, it defaults to 232 - 1.

As an example, let's suppose we want to extract out the numbers from the string '10,20,30'. What we could do is simply call split() on this string, specifying the ',' character as the delimiter.

The split() method would chop off the string at every occurrence of , in the string and give back the left out segments of substrings in tte form of an array, i.e. the value ['10', '20', '30'].

Shown below are a couple more examples:

'Hello'.split()
["Hello"]
'H e l l o'.split(' ')
["H", "e", "l", "l", "o"]
'H,e,l,l, o'.split(',')
["H", "e", "l", "l", " o"]

In the first statement, since no argument is provided to split(), we get an array returned containing the string as it is. In the second one, we split the string apart at every space character. A similar case applies to the third statement.

However, an important thing to note here is the return value of the third statement; in particular, the fifth character in the returned array. It's ' o' with a space at its start as in the original string, NOT 'o' without a space.

This suggests that split() just throws away the given separator, leaving the rest of the string absolutely untouched.

Moving on, it's quite common to split strings using '' as the separator.

If separator is an empty string (''), we get an array of characters returned.

'Hello'.split('')
["H", "e", "l", "l", "o"]

This behavior is frequent in programs that ought to modify certain characters of a given string. Making these modifications directly in the string is challenging in JavaScript since it treats strings as immutable data.

By converting a string into an array of characters, we can modify the individual elements of the array and then later on, using the array method join(), get back a string.

Here's a quick example:

var str = 'Good';
var strArr = str.split('');
strArr[0] = 'F';

console.log(strArr.join(''));
Food

We'll discover more about the join() array method in JavaScript Arrays — Array Methods: join().

Now let's see how to work with the limit parameter of split().

By default, limit is set to an extremely large value, i.e. 232 - 1, which won't ever be touched in almost all frontend string processing problems.

We could also manually provide an integer value to limit, in which case the array returned would have only that many elements,at max; not more than that.

Shown below are a couple of examples:

'Hello'.split('')
['H', 'e', 'l', 'l', 'o']
'Hello'.split('', 10)
['H', 'e', 'l', 'l', 'o']
'Hello'.split('', 2)
['H', 'e']
'Hello'.split('', 0)
[]

In the first statement, we call split() without a limit argument, and thus get an array of characters returned. In the second statement, the provided limit is larger than the total number of characters in the string, likewise we get the same array returned as before.

As limit is reached, string splitting is put to a halt and the array created thus far is returned. This is exactly what happens in the third statement. As soon as two elements are obtained in the splitting process, the method exits, ignoring the rest of the string.

In the last statement, limit is 0 and hence we get an empty array returned, with no more than 0 elements. In practice though, we won't need such a limit.

Slicing strings

Another common practice while working with strings is to extract a small portion out of a given string. This is commonly referred to as slicing a string.

In JavaScript, there are mainly two methods used for string slicing needs — slice() and substring().

Let's see each one.

slice()

The slice() method slices a string from a starting position to an ending position, and returns back the slice.

Let's see its syntax:

string.slice([start[, end]])
  • start specifies the index where to begin the slicing. It defaults to 0.
  • end specifies the index where to end the slicing. This is exclusive. It defaults to the length of the string.

Time to see some examples:

'Hello'.slice()
'Hello'
'Hello'.slice(1)
'ello'
'Hello'.slice(1,2)
'e'

Note that the end argument is exclusive, that is, slicing ends right before the given end index.

The most interesting aspect of slice() is that we could provide it negative indexes as well. Such an index is computed from the end of the string.

For example, -1 points to the last character, -2 points to the second last character, and so on and so forth.

Consider the following code:

'Coding'.slice(-2)
'ng'
'Coding'.slice(-2, -1)
'n'
'Coding'.slice(0, -1)
'Codin'

In the first call to slice(), we retrieve the last two characters of the string str. In the second call, we retrieve the second last character of str. In the third call, we slice the string from the very beginning to the very end, leaving off the last character.

So this is how slice() works. Let's now look into a similar method — substring().

substring()

Akin to slice(), the substring() method slices a string from a starting position to an ending position and returns back the slice.

So then what's the difference between slice() and substring()?

Difference between slice() and substring()

The main difference is the way given arguments are perceived in the internal implementations of slice() and substring().

If the start argument to substring() is greater than end, the arguments are swapped. This doesn't happen with slice().

Moreover, if a given argument to substring() is negative, it is taken to be 0 unlike slice() which starts counting from the end of the string.

An illustration follows for the first case:

'Hello'.slice(2, 0)
''
'Hello'.substring(2, 0)
'He'

And now for the second case:

'Hello'.slice(-2, -1)
'l'
'Hello'.substring(-2, -1)
''

In the second statement here, both the negative arguments to substring() get converted to 0, likewise the call substring(-2, -1) translates to substring(0, 0), which simply returns an empty string.

String replacement

The last utility left to be covered in this chapter is that of string replacement. The idea is to replace given substrings in a string with other strings.

The string methods replace() and replaceAll() allow us to perform replacements of given substrings within a string in JavaScript.

Let's start with replace().

replace()

The replace() string method replaces a substring inside a string with a given value.

The syntax of replace() is shown as follows:

string.replace(searchStr, replaceStr)
  • searchStr is the string to search in string.
  • replaceStr is the string to replace the first occurrence of searchStr in string with.

Here's an easy way to remember the order of arguments in replace(): we need to first search for something within a string before we could replace it, right? Likewise, the string to search for comes first, followed by the string to replace it with.

Let's perform a couple of replacements on some strings:

'Hello World!'.replace('World', 'Programmer')
'Hello Programmer!'
'Good'.replace('G', 'F')
'Food'
'Good'.replace('GOOD', 'FOOD')
'Good'
'3 x 3 = 9'.replace('3', '4')
'4 x 3 = 9'

In the first statement, we replace the substring 'World' from the string 'Hello World' with 'Programmer' and thus get the returned value. In the second statement, we accomplish a similar notion, just this time replacing a single character.

The third statement conveys an imporant point regarding replace(). That is, replace() searches for searchStr case-sensitively. Since 'Good' doesn't contain 'GOOD' in it (case-sensitively), the third replace() call has no effect.

In addition to this, as the last statement shows, replace() only replaces the first occurrence of searchStr inside the main string — in this case, only the first occurrence of '3' to give '4 x 3 = 9'.

To replace all occurrences, we could use the replaceAll() method.

replace() and regular expressions

Even the replace() method could replace all occurrences of a given substring in a main string but only if the first argument is a regular expression with the global (g) flag set.

Regular expressions represent a slightly more advanced, but still not that difficult, area of JavaScript and programming, in general. They are covered from scratch, in detail, in our dedicated JavaScript Regex Course.

Below shown is an example of using a regular expression with replace() to replace all occurrences of '3' in the last string above:

var str = '3 x 3 = 9';
var newStr = str.replace(/3/g, '4'); // Replace all 3's with 4's

console.log(newStr);
4 x 4 = 9

Here, /3/g is the regular expression. Let's quickly understand what it means...

// is how we denote regular expressions literally in JavaScript. In between these, we put a pattern to be matched in a given string. In this case, the pattern is trivially 3, which says to match the character '3' in a given string.

Finally the g at the end of the expression instructs the regular expression engine to search for all occurrences of '3' in a given string and not just stop at the first one.

This is just the very beginning of regular expressions. We could make extremely complex patterns using them that could match a huge variety of substrings.

You could make yourself able to understand all the complexities of regular expressions in JavaScript by taking our JavaScript Regular Expressions Course.

replaceAll()

The replaceAll() method is similar to replace(), except for one obvious thing.

replaceAll() replaces all occurrences of a substring in a string with another value.

Syntactically, it's exactly the same as replace().

string.replaceAll(searchStr, replaceStr)

Restating it:

  • searchStr is the string to search in string.
  • replaceStr is the string to replace all occurrences of searchStr in string with.

Consider the snippet below:

'Food'.replaceAll('o', 'e')
'Feed'
'3 x 3 = 9'.replaceAll('3', '4')
'4 x 4 = 9'
'Hello'.replaceAll('a', 'e')
'Hello'

In the last statement, since 'a' doesn't exist in the given string 'Hello', nothing is replaced and the string is returned as is.

Moving on

Strings are vital to JavaScript and so are methods to strings. Without the methods, strings can only be written and as-it-is displayed; no functionality and no fun!

Now it may take you some time to master everything that we learnt in this chapter, i.e. the names of different methods, the types and order of their arguments, their return values, and so on. That 'some' time can become 'a lot' of time if you don't practice.

So open up the console and start experimenting.

Take note of the key points discussed in this chapter. Try to relate method functionalities with their names. This way you can ensure a solid grip over JavaScript string methods in no more than just a couple of days!

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage