JavaScript Function Construction

Building A Basic Function Constructor

Austin Smith
Level Up Coding

--

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

On this journey we call JavaScript, one of the most useful tools (if you can call it a tool) I have been using more and more are Function Constructors.

Why am I finding Function Constructors so useful? Because they allow me to write less code and be more effective with the code that I am writing. Function Constructors also allow me to encapsulate the variables, properties or functions that are specific to an invocation or operation I want to execute, and make sure whatever they are going to do won't start messing up other parts of my project.

Many libraries such as jQuery make heavy use of function constructors, and if you ever want to see how the pros do it, I highly suggest taking a look at jQuery’s source code. It is open source and free, and available with or without comments on their home page.

Function Constructors are great for compartmentalizing variables, functions and contextual environments that I want to use in different parts of a project.

Say I have the same POST request to a server in 3 or 4 different places in my code. That is 3 or 4 times I have to write out the same 15 or 20 lines for each request.

Well, instead of writing out the request every single time I want to retrieve data from my server, I can write the request once in a function constructor, import that object to where ever I am making that request, call the function that is bound to the object I imported, and invoke the function with one or two lines.

I may still be new to programming, and my path in this journey we call JavaScript is only just beginning, but I am going to make a bold statement. A statement that might offend those who possess knowledge I might some day hope to obtain:

Function Constructors are the essence of closure, and the pinnacle of Functional Programming in JavaScript.

Let’s get started.

SO IT BEGINS

Theatrics aside, let’s get down to business and define what a Function Constructor is. A Function Constructor is a plain old, normal function that is used to construct objects. That doesn’t sound special, and on a surface level, it isn’t.

The magic only begins when we add a very special, elusive keyword: ‘THIS’

The ‘THIS’ keyword, when used within a Function Constructor, is a reference to the object it is created in. It allows us to assign properties to the object it is creating from within the function we are writing. ‘THIS’ also allows us to mutate or change the properties of an object from within the object itself.

Why is that important?

Let’s look at a basic example:

function Person(firstname, lastname) {
this.firstname = firstname
this.lastname = lastname
}

Here we have a function called Person. It is accepting two arguments, then setting the two arguments as values to properties that are defined within the function. But it is also using the ‘THIS’ keyword.

What ‘THIS’ does is bind the properties to the object it is created in. If we console.log() ‘THIS’ and invoke the function, we can take a look at what ‘THIS’ is doing:

function Person(firstname, lastname) {
this.firstname = firstname
this.lastname = lastname
}
console.log(this)Person()

The console will then spit all of this out:

<ref *1> Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(util.promisify.custom)]: [Function (anonymous)]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(util.promisify.custom)]: [Function (anonymous)]
},
firstname: undefined,
lastname: undefined
}

So what is happening?

We see an object called ‘global’ that is filled with a whole bunch of rather common functions you might have seen before.

If you execute this function in an internet browser, you will see a WHOLE LOT more functions.

What we are looking at is the Global Execution Context. What is the Global Execution Context?

Here is a pull-quote from a blog I wrote a couple weeks ago:

The Global Context is exactly what you think it might be. It is a default execution context created every time a Javascript file is ran. The global execution context performs vital functions: It creates a global object with a whole bunch of methods and variables inside of it, and it sets the ‘this’ keyword in it’s execution context to that global object. Anything written outside of a function is written at the global execution context, or in the global context. If you have ever tried accessing ‘this’ in the global context, and then tried accessing ‘this’ within an object, you will notice that you get two very different results.

Why do we see the Global Execution Context when ‘THIS’ is written in the function?

Well, we are invoking the Person function at the global level. If a function is invoked at the global object(window), ‘THIS’ points to global execution context.

We also see our two properties first and last name at the bottom.

That is good. Real good. But that’s not what we want.

We want to create a new object where ‘firstname’ and ‘lastname’ appear as key/value pairs.

So let’s fix that.

What we can try to do is create a new object with that function using the keyword ‘NEW’ and store it to a variable. Then we can console.log() the variable ‘john’ to see if it worked:

function Person(firstname, lastname) {
this.firstname = firstname
this.lastname = lastname
console.log(‘inside the function:’, this)
}
var john = new Person()console.log(‘outside the function:’, john)-------------------->> inside the function: Person { firstname: undefined, lastname: undefined }
>> outside the function: Person { firstname: undefined, lastname: undefined }

We now see that when we call ‘THIS’ from inside the function, and create an object using the ‘NEW’ keyword that is stored to a variable, the Execution Context changes, since the Person function is being invoked at the context of the ‘new’ keyword.

‘THIS’ now points to the object we are creating, and since JavaScript creates a new execution context every time a function is invoked, the execution context points the ‘THIS’ variable to the new empty object is creating,and returns that object automatically.

It is a function that constructs an object.

A Function Constructor…you might say.

Let’s expand on this a bit.

We might as well pass some arguments into the object so we can get rid of those ‘undefined’ values:

function Person(firstname, lastname) {
this.firstname = firstname
this.lastname = lastname
}
var john = new Person(‘john’, ‘smith’)console.log(‘Object:’, john)-------------------->> Object: Person { firstname: ‘john’, lastname: ‘smith’ }

And since all functions are objects in JavaScript, we can also access the ‘firstname’ and ‘lastname’ properties we are creating with the Member Access Operator (or dot notation):

console.log(john.firstname)-------------------->> john

Or:

console.log(john.lastname)-------------------->> smith

We can also…and this is where things start getting interesting…
add a function to our function constructor:

function Person(firstname, lastname) {
this.firstname = firstname
this.lastname = lastname
this.hello = function() {
return ‘Hello, ‘ + this.firstname + ‘ ‘ + this.lastname + ‘.’
}
}

Then access and invoke the function:

console.log(john.hello())-------------------->> Hello, john smith.

So we have a function that is creating an object that is creating a function which is also an object…

Yes, exactly.

CUSTOM TIME FUNCTION CONSTRUCTION

So I have always disliked the way JavaScript’s new Date() features work.

I always find myself having to format and reformat things over and over again, and it would be really nice to just have a simple way to get a formatted string of the current time.

So, lets do it.

Let’s modify the example above, and try to get the constructor to just output the new Date() function:

function getTime() {
const date = new Date()
this.now = function() {
return date
}
}
var time = new getTime()console.log(time.now())-------------------->> 2020–03–19T00:33:46.820Z

Ok great. But we want this to be formatted.

No problem. The now() function we are writing is a normal JavaScript function, and so we can assign variables, execute boolean comparisons, concatenate strings, etc… just like we normally would

At the moment it is only acting like an alias for the new Date() function built into JavaScript, so let’s make it do a little more than that:

function getTime() {
const date = new Date()
this.now = function() { // We can convert the built in getHours() method to conform to a 12 hour clock by taking the current time and finding it’s remainder when divided by 12 with the modulo operator
// Example: If it is 13:00 on a 24 hour clock, and 13 % 12 leaves a remainder of 1, then that means it is 1 o’clock
let hours = date.getHours() % 12 // If the current hour is less than or equal to 12, return AM, otherwise return PM let ampm = date.getHours() <= 12 ? ‘AM’ : ‘PM’ // Simple alias for the built in getMinutes() method let minutes = date.getMinutes() // On a 24 hour clock, if it is midnight, it is 24:00. 24 % 12 is 0, which we don’t want.
// So we can use a ternary operator to check if it is midnight, and if it is, return 12
hours = hours ? hours : 12 // Simple formatting that adds a zero before any minute of an hour that is less than 10. minutes = minutes < 10 ? ‘0’+ minutes : minutes // Everything we just wrote rolled into one nice simple string let time = hours + ‘:’ + minutes + ‘ ‘ + ampm return time
}
}
var time = new getTime()console.log(time.now())

This should return whatever the current time is for whenever you run this script:

Nice.

JavaScript uses the internal clock of your PC for it’s Date functions, so you can mess around with the clock on your computer to test out if it works properly.

We can keep going too. We can as many functions as we want to this constructor without worrying how it will effect code outside of this function. There are no side effects:

Let’s get add the current day of the month:

this.day = function() {
let day = date.getDate()
return day
}

And the month:

this.month = function() {
let month = date.getMonth()
// We need to add 1 to the month number because in JavaScript, month numbers start at zero, not 1; just like the indices of an array
return (month + 1)
}

And the year:

this.year = function() {
let currentYear = date.getFullYear()
return currentYear
}

All simple stuff, but important for what is next.

We can add 1 more function that references all the methods we wrote within the function constructor, and combine all of these methods into 1 method that gives us a single properly formatted date string:

this.formattedDate = function() {
let time = this.now()
let day = this.day()
let month = this.month()
let year = this.year()
const formattedDate = ‘(‘ + time + ‘)’ + ‘ ‘ + month + ‘/’ + day + ‘/’ + year return formattedDate
}

Which will give us a nice string which we can use where ever we want to display the current time:

and we can reuse this constructor anywhere we want by calling 2 lines of code:

var time = new getTime()console.log(time.formattedDate())

We can also get individual pieces of the date by calling all of the other functions we constructing as well, making this function constructor very handy, and we never have to worry about fumbling around with new Date() again.

MISSION COMPLETE

After working on this blog for most of the day today, I realized it might be a good idea to divide the constructing of our new getTime function constructor, and how to export/import it in other scripts, or other frameworks such as React into 2 blog posts. This one turned out to be much larger than I anticipated, and a few other ideas for examples didn’t work out too well. The Postgres modules I installed to work with React were causing a lot of problems.

For the next blog I write, I will properly detail how you can re-use this function constructor in vanilla JS, as well as React, and potentially add a little more functionality to the constructor itself. I might have 1 or 2 other examples as well, I don’t really know.

So I hope this blog was a good introduction to Function Constructors, and I look forward to expanding upon everything I detailed here
in the next blog I write. Thank you for reading.

JavaScript Function Construction

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

--

--