Code Endeavor's Blog

Javascript Simplified Part I
Objects, Prototypes, and Classes

Introduction

I have been writing javascript code for my job since the turn of the century. I have always enjoyed coding with it, and feel that it still gets a bad wrap by a large portion of developers. This series of blog posts is meant to be as a means to get started using the language quickly and hopefully gain an appreciation of how the programming language of the web has evolved. This entry covers the history of javascript objects, including constructors, properties and methods.

Javascript Objects

In javascript, we can easily create a new object.

var person = new Object();

There is a short-hand notation for creating a new Javascript object that allows a new object to be created using a pair of curley brackets.

var person = {};

We can easily add properties to the object using the dot-notation (putting a period between our object instance and the property name we wish to define) or bracket notation (useful when property name needs to be determined in code).

var person = {};
person.firstName = 'Bilbo';       //dot notation
person['lastName'] = 'Baggins';   //bracket notation

console.log(person.firstName + ' ' + person.lastName);

We can make our code even more concise by initializing our person object with its properties upon creation / construction.

var person = { firstName: 'Bilbo', lastName: 'Baggins' };
console.log(person.firstName + ' ' + person.lastName); //outputs Bilbo Baggins

If you are not familiar with Javascript Object Notation (JSON), consider yourself introduced.

Classes Supported From Beginning

While that example above works, it does not offer a "blueprint" for developers who wish to use our object. A more formalized way to represent a Person is needed. Javascript has always been able to emulate classes even before its newer versions through the use of functions.

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;

  this.getFullName = function() {
    return firstName + ' ' + lastName;
  }
}

var p = new Person('Bilbo', 'Baggins');
console.log(p.getFullName());  //outputs Bilbo Baggins

While this works, it is inefficient, since every time you create a Person object you will copy along all the function definitions for its methods, in this case getFullName.

Prototypes

In javascript, prototypes allow you to customize the methods that get added to your objects when they are created. Their use provides the blueprint for the method only once (on the prototype itself). Changing our example above to use prototypes is quite simple.

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.getFullName = function() {
  return firstName + ' ' + lastName;
}
var p = new Person('Bilbo', 'Baggins');
console.log(p.getFullName());  //outputs Bilbo Baggins

Javascript classes

Javascript is a language that follows specifications defined by the European Computer Manufacturers Association (ECMA). In 2015, the specification for classes was added. This was the 6th version of javascript formalized in the year 2015. Therefore this version is typically known as ES6 or ECMAScript 2015.

Using the class keyword allows our javascript to look more like traditional Object Oriented languages.

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}
var p = new Person('Bilbo', 'Baggins');
console.log(p.getFullName());  //outputs Bilbo Baggins

Object Properties

You may have noticed that our object has a method for getting the full name. It would be nice if we could have that read as a property instead (p.fullName). ES5 introduced a new way to defined getters/setters on an object called defineProperties.

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Object.defineProperties(
  Person.prototype, {
    fullName: {
      get: function() {
        return this.firstName + ' ' + this.lastName;
      },
      set: function(value) {
        this.firstName = value.split(' ')[0];
        this.lastName = value.split(' ')[1];
      }
    }
  }
);

var p = new Person('Bilbo', 'Baggins');
console.log(p.fullName);      //outputs Bilbo Baggins
p.fullName = 'Frodo Baggins'; //BONUS: this calls the setter
console.log(p.firstName);     //outputs Frodo

Of course, ES6 provides an even better way of defining properties with classes.

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  get fullName() {
    return this.firstName + ' ' + this.lastName;
  }
  set fullName(value) {
    this.firstName = value.split(' ')[0];
    this.lastName = value.split(' ')[1];
  }
}
var p = new Person('Bilbo', 'Baggins');
console.log(p.fullName);      //outputs Bilbo Baggins
p.fullName = 'Frodo Baggins'; //BONUS: this calls the setter
console.log(p.firstName);     //outputs Frodo

Hopefully this entry was helpful to you. Check back later for more articles in this series 😉.