JavaScript Objects and Object Constructors

JavaScript Objects and Object Constructors

This article will guide you to write clean, readable, and maintainable javascript code for your medium to extensive application.

·

5 min read

Organizing code is arguably one of the most frightening parts of Javascript mostly because Javascript is an unopinionated language i.e. Javascript doesn’t force you to write code in a specific way. But when your program becomes complex, it becomes hard to maintain unless you take care to organize your code.

This blog is going to cover one of the popular design patterns that occur in modern javascript code i.e. Objects and Object Constructor.

Prerequisite - you need to have a basic knowledge of javascript.

Learning Outcomes

By the end of this blog, you should be able to do the following:

  • Explain how Object and Object Constructor can be helpful.
  • Explain the pros and cons of this design pattern
  • Explain some best practices of using this design pattern

Objects and Object Constructors

You can use objects in a simple manner by grouping things together. Take these examples from a 'tic tac toe' game:

// example one
const playerOneName = "Raja"
const playerTwoName = "Rana"
const playerOneMarker = "X"
const playerTwoMarker = "O"

// example two
const playerOne = {
  name: "Raja",
  marker: "X"
}

const playerTwo = {
  name: "Rana",
  marker: "O"
}

The second approach makes writing code so much simpler. Let's say you don't know the name of the player and want to print the winning player’s name.

function gameOver(winningPlayer) {
  console.log("Congratulations!")
  console.log(winningPlayer.name + " is the winner!")
}

But what if we are not making two player game but some eCommerce site with a large inventory, then we need to use objects to group items’ names, descriptions, prices, etc. In fact, writing each property manually is not feasible either. We need a cleaner way to create objects which brings us to Object Constructor.

Object Constructors

When we have a specific type of object which we need to duplicate like a player or inventory item, we can use Object Constructor, which is a function that looks like this

function Player(name, marker) {
  this.name = name
  this.marker = marker
}

and which you use by calling the function with the keyword new.

const player = new Player('rana', 'X')
console.log(player.name) // 'rana'

Just like with objects created using the Object Literal method, you can add functions to the object:

function Player(name, marker) {
  this.name = name
  this.marker = marker
  this.sayName = function() {
    console.log(name)
  }
}

const player1 = new Player('Raja', 'X')
const player2 = new Player('also Raja', 'O')
player1.sayName() // logs 'Raja'
player2.sayName() // logs 'also Raja'

The Prototype

All objects in JavaScript have a prototype. Stated simply, the prototype is another object that the original object inherits. The concept of the prototype is an important one for understanding Prototypal Inheritance.

If you’re using constructors to make your objects it is best to define functions on the prototype of that object. Doing so means that a single instance of each function will be shared between all of the Student objects. If we declare the function directly in the constructor, as shown in the above example, that function would be duplicated every time a new Student is created. In this example, that wouldn’t really matter much, but in a project that is creating thousands of objects, it really can make a difference.

function Student(name, grade) {
  this.name = name
  this.grade = grade
}

Student.prototype.sayName = function() {
  console.log(this.name)
}
Student.prototype.bunkClass = function() {
  console.log("Eh.. bunk Class?")
}

The recommended way of setting the prototype of an object is Object.create. Object.create very simply returns a new object with the specified prototype and any additional properties you want to add. For our purposes, you use it like so:

function Student() {

}

Student.prototype.sayName = function() {
  console.log(this.name)
}

function EighthGrader(name) {
  this.name = name
  this.grade = 8
}

EighthGrader.prototype = Object.create(Student.prototype)

const carl = new EighthGrader("wasim")
carl.sayName() // console.logs "wasim"
carl.grade // 8

A warning… this doesn’t work:

EighthGrader.prototype = Student.prototype

because it will literally set EighthGrader’s prototype to Student.prototype (i.e. not a copy), which could cause problems if you want to edit something in the future.

Let's see one more example

function Student() {

}

Student.prototype.sayName = function() {
  console.log(this.name)
}

function EighthGrader(name) {
  this.name = name
  this.grade = 8
}

// don't do this!!!
EighthGrader.prototype = Student.prototype

function NinthGrader(name) {
  this.name = name
  this.grade = 9
}

// not again!
NinthGrader.prototype = Student.prototype

NinthGrader.prototype.sayName = function() { console.log("HAHA") }

const wasim = new EighthGrader("wasim")
wasim.sayName() 
// uh oh! this logs "HAHA" because we edited the sayName function

If we had used Object.create in this example, then we could safely edit the NinthGrader.prototype.sayName function without changing the function for EighthGrader as well.

Pros and Cons

There are many people who argue against using a constructor at all because a constructor looks like a regular function but does not behave like a regular function at all. And if you use the constructor without using a new keyword it will not work but it won't produce any error either.

The main takeaway is that while constructors aren’t necessarily evil, they aren’t the only way, and they may not be the best way either. Of course, this doesn’t mean that time learning about them was wasted! They are a common pattern in real-world code and many tutorials that you’ll come across on the net.