Bake A Javascript Library using Vanilla JS (Part 3)

Saurav Tiru
6 min readAug 3, 2022

--

Before you go ahead, this is a mini-series where we start from ground zero to a shippable Javascript Date Library 📅

View the previous article to be on the track! 😄

Let’s Go! 🚀

Dude, you are making us hungry.

Previously —

We utilized ES Modules and utilizedimport & export syntax to and apply tree-shaking methods to pass functions and also utilizingpackage.json to make our node application understand all the processes above!

Next, we learn to utilize Prototypal Inheritance & use techniques like chaining & immutability to make our library more robust! 🚀

Content

  1. Constructor + Prototypal Inheritence
  2. Chaining
  3. Immutability

Constructor + Prototypal Inheritance

Blueprint to your next library!

If someone is coming from OOP(s) (Object Oriented Programming) concept, one would understand how Classes work. You create an instance of the class and utilize the inner methods.

“class” keyword was added to JavaScript since ES6 (ECMAScript 2015)

JavaScript is not an object-oriented language, it was not designed to be one. Theclasskeyword is instead a syntactical sugar & internally it utilizes Prototypal Inheritance

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects.

So let’s convert our existing import & export structure to a Prototypal approach!

In our time.js we shall introduce a constructor function named Time

/*time.js*/function Time(date) {
this.date = new Date(date)
}
...rest of the code...

As you can see this is a constructor function which accepts any date parameter, which later utilizes this , which refers to the current instantiation.

What’s happening above? -

  • We create a constructor function.
  • It accepts a parameter named date.
  • The date is passed to create a new JS Date object.
  • which is stored in this.date , where this refers to the current instance.

Phew, that's a lot of change, or is it? 😅 Next! We need to use Prototypal Inheritance and modify our existing methods so that our Time constructor has those methods attached.

/* time.js */
...rest of the code...
Time.prototype.getDay = function () {
let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
return days[this.date.getDay()];
}
Time.prototype.getMonth = function() {
let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
return months[this.date.getMonth()];
}
Time.prototype.addDays = function (n) {
this.date.setDate(this.date.getDate() + n);
}
export default Time

What’s happening above? -

  • Methods like getDay(), getMonth() & addDays() are added to the prototype chain of Time constructor.
  • Finally, we export this at the end of the file using export.
  • Default is used to export only one value from a file which can be a class, function, or object, which in our case is Time.
  • I would write a detailed article on Prototypal Inheritance.
  • It’s a very important JS topic, as the JS we know today is built entirely on this. 🚨

Finally, we need to modify our index.js to accommodate the new prototypal changes.

/*index.js*/import Time from "./time.js"let Christmas = new Time('December 25, 2021');let day = Christmas.getDay(Christmas);
let month = Christmas.getMonth(Christmas);
console.log(day, month);
Christmas.addDays(7);
console.log(Christmas);

What’s happening above? -

  • We use import and import the Time constructor in our file.
  • We use Time constructor to create a new Time instance. 🚧
  • We refer to prototypes by using instance.prototype syntax.

If everything is done right, on refreshing the browser you should see this!

You can see all the prototypes in the Time.

Chaining ⛓

C H A I N is as simple as it sounds.

Pat yourself in the back! You just created a very sleek, not-yet-ready, but working prototype (no pun intended) 😅. Let’s add some flavor to it!

What does it mean by Chaining?

Method Chaining is a programming strategy that simplifies and embellishes your code. It is a mechanism of calling a method on another method of the same object.

Our library doesn’t support this as of now, how does it work though?

For a method to be chainable, it needs to return its context for the next method to utilize it.

So this works only in the existing methods that DO NOT return anything already.

So let’s make add 2 new methods called addMonths & addYears to our time.js file.

/*time.js*/
...rest of the code...
Time.prototype.addMonths = function(n) {
this.date.setMonth(this.date.getMonth() + n);
return this
}
Time.prototype.addYears = function(n) {
this.date.setFullYear(this.date.getFullYear() + n);
return this
}
...rest of the code...

What’s happening above? -

  • These methods modify our existing this.date variable.
  • But we also return this , this keyword holds the entire instance context (variable, prototypes)

Let’s put it to action 🚀, modify our index.js

/*index.js*/...rest of the code....Christmas.addDays(1).addMonths(1).addYears(1)
console.log(Christmas)
...rest of the code...

What’s happening above? -

  • We are chaining three methods addDays() , addMonths() & addYears()
  • Suppose the current date object is instantiated with December 25, 2021 .
  • We are adding 1 Day, 1 Month, and 1 Year to it.
  • What would be the output? Let’s check it out below 🔍.
We are time traveling doc.

As you can see —

  • 1 day makes it December 26, 2021.
  • 1 month makes it January 26. 2022.
  • 1 year makes it January 26, 2023. ⏲

Chaining is very easy, seriously!

Immutability

Unsplash had no image for immutability. SAD.

Okay, take a breath soldier, you made it through the battlefields of Javascript! Finally, let’s understand the topic of Immutability.

Let’s understand it via this analogy-

A princess kisses a frog hoping it will turn into a handsome prince. The concept of immutability says that a frog will always be a frog. The immutability concept is mainly originated from functional and object-oriented programming. Whenever we want to make changes to some data (for example to an object or an array) we should get a new object back with the updated data instead of directly modifying the original one.

Until now, the way our Javascript Date Library has been designed, we are modifying the instance every time we call one of our methods, which are in turn being called through a proto chain.

For a robust library, we do expect sometimes that we don't directly modify the instance, but rather create a new instance, have it stored in another variable and take things forward ahead. This keeps the logic clean and proceeds towards achieving true Immutability.

Let’s start!

Let’s modify our time.js and modify our chained methods -

/*time.js*/
...rest of the code...
Time.prototype.addDays = function (n) {
let newDate = new Date(this.date)
newDate.setDate(this.date.getDate() + n);
return new Time(newDate)
}
Time.prototype.addMonths = function(n) {
let newDate = new Date(this.date)
newDate.setMonth(newDate.getMonth() + n);
return new Time(newDate)
}
Time.prototype.addYears = function(n) {
let newDate = new Date(this.date)
newDate.setFullYear(newDate.getFullYear() + n);
return new Time(newDate)
}
...rest of the code...

What’s happening above? -

  • We are creating a new JS Date Object every time one of the chained methods is called.
  • Then the newDate object is used to perform the underlying action the method is supposed to do (addDay, addMonth…etc)
  • return the newly modified newDate Date object.
/*index.js*/...rest of the code...
console.log("before", Christmas)
let modified = Christmas.addDays(1).addMonths(1);
console.log("after", modified, Christmas)
...rest of the code....

What’s happening above? -

  • We are storing the modified instance of Christmas in a variable named modified .
  • To confirm we are logging twice, once with before and another comparing post-modification.
The existing instance remains same

Without Immutability, it would look something like this…..

Existing instance gets updated.

This concludes Part 3, if you have any doubts or improvements for this article please do comment, and if you liked it share a few applause 😄.

In Part 4, we shall explore adding Hooks! Ahoy 🚢 and explore more advanced topics which will bring us closer to the end goal of a Shippable Javascript Date Library!

****************************************************************

This post was inspired by — https://gomakethings.com/ , please do check out this wonderful blog based on pure Javascript.

I’m Saurav Tiru, Front End Engineer at building UI at Radius.

I would be posting articles related to Front End Engineering, Photography, and Video Editing every week!

--

--