Extending the Javascript String Prototype

Published Dec 27, 2017Last updated Jan 19, 2018
Extending the Javascript String Prototype

While JavaScript string provides lots of methods to manipulate strings with, what can we do if we want some functionality not present in the string prototype?

Let's consider this example:

You have a string containing sentences and you need to capitalize the beginning of every sentence. The sentence's first letter might/might not be capitalized, we don't know the number of sentences in the string, and we have to capitalize every sentence in the string.

We have our sentences like:

let sentenceOne = "these violent delights have violent ends And in their triumph die, like fire and powder Which, as they kiss, consume. my bounty is as boundless as the sea, My love as deep; the more I give to thee, The more I have, for both are infinite. thus with a kiss I die. Don't waste your love on somebody, who doesn't value it. Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.for never was a story of more woe than this of Juliet and her Romeo.";
let sentenceTwo = "These are. words pretending to. be a sentence.";

The simplest solution would be to write a function that goes through a string, finds all of the sentences, and then capitalizes the first letter of the sentence.

This is how we might do it:

function capitalizeSentence ( str ) {
  // let's split the string after every '.', Since every sentence ends with a dot.
  let sentences = str.split('.');

  // let's map over our sentences array 
  sentences.map( function (sentence) {
    console.log(sentence);
  });
}

capitalizeSentence( sentenceOne );

In the console we can see:

"these violent delights have violent ends And in their triump die, like fire and powder Which, as they kiss, consume"
" my bounty is as boundless as the sea, My love as deep; the more I give to thee, The more I have, for both are infinite"
" thus with a kiss I die"
" Don't waste your love on somebody, who doesn't value it"
" Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow"
"for never was a story of more woe than this of Juliet and her Romeo"
""

Not something I expected. There's an empty string at the end of the sentences array. Most of the string begins with a space.

How do we fix it? Should we fix it?

To get rid of the empty string, we can first check to see if a sentence is not empty and then continue further. We can then check to see if the first character of the string is spaced or not and then perform our logic.

The code for this would look like this:

function capitalizeSentence ( str ) {
  // let's split the string after every '.', Since every sentence ends with a dot.
  let sentences = str.split('.');
  let updated = [];

  // let's map over our sentences array 
  sentences.map( function (sentence) {
    if ( sentence ) {
      // if the first character is not spaced
      if ( sentence[0] !== ' ' ) {
        let output = sentence.charAt(0).toUpperCase() + sentence.slice(1);
        updated.push( output );
      }
      // if the first character is spaced
      else {
        let output = sentence.charAt(1).toUpperCase() + sentence.slice(2);
        updated.push( ' ' + output );
      }
    }
  });

  // let's join our array with ., the same character we split it with.
  let final = updated.join('.');

  // if the sentence ends with ., let's add it to our final output as well.
  if ( str.endsWith('.') ) {
    final += '.';
  }

  return final;
}

Of course, this is not the best code and will fail if the sentence contains multiple spaces after the . (period) but I am sure you can handle it.

Now this works. We can test it by calling our function:

console.log( sentenceOne );
console.log( capitalizeSentence( sentenceOne ) );

And in the console we can see:

"these violent delights have violent ends And in their triump die, like fire and powder Which, as they kiss, consume. my bounty is as boundless as the sea, My love as deep; the more I give to thee, The more I have, for both are infinite. thus with a kiss I die. Don't waste your love on somebody, who doesn't value it. Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.for never was a story of more woe than this of Juliet and her Romeo."
"These violent delights have violent ends And in their triump die, like fire and powder Which, as they kiss, consume. My bounty is as boundless as the sea, My love as deep; the more I give to thee, The more I have, for both are infinite. Thus with a kiss I die. Don't waste your love on somebody, who doesn't value it. Good night, good night! parting is such sweet sorrow, That I shall say good night till it be morrow.For never was a story of more woe than this of Juliet and her Romeo."

But wouldn't it be better if we can directly call the method on our string, like:

"Sentence one. sentence two and. sentence three.fourth sentence is best.".capitalize();

Well, we can.

We can do this by extending the string.prototype. We just have to make a minor change in our method as well as add a new line of code.

function capitalizeSentence ( str ) {

  // if the string is not provided, and if it's called directly on the string, we can access the text via 'this'
  if ( ! str ) { str = this; }

  // let's split the string after every '.', Since every sentence ends with a dot.
  let sentences = str.split('.');
  let updated = [];

  // let's map over our sentences array 
  sentences.map( function (sentence) {
    if ( sentence ) {
      // if the first character is not space
      if ( sentence[0] !== ' ' ) {
        let output = sentence.charAt(0).toUpperCase() + sentence.slice(1);
        updated.push( output );
      }
      // if the first character is space
      else {
        let output = sentence.charAt(1).toUpperCase() + sentence.slice(2);
        updated.push( ' ' + output );
      }
    }
  });

  // let's join our array with ., same character we split it with.
  let final = updated.join('.');

  // if the sentence ends with ., let's add it to our final output as well.
  if ( str.endsWith('.') ) {
    final += '.';
  }

  return final;
}


// let's add our method on String prototype.
String.prototype.capitalize = capitalizeSentence;

Now, we can directly call this method on our string.

console.log( "Sentence one. sentence two and. sentence three.fourth sentence is best.".capitalize() );

// output
"Sentence one. Sentence two and. Sentence three.Fourth sentence is best."

And this works as expected.

Hope this tutorial was interesting and helpful.

Discover and read more posts from Dhruv Kumar Jha
get started