Initializing a Class in Node

Ever used a Node.js module that was instantiated like so: something = new Something(). We’re used to it with built in types like Date() but how are the developers of Node modules doing this and why would you want to?

Object Prototypes

Every JavaScript object has a prototype. It could be a String, Function, Array, whatever. By default every object has a set of properties set by its prototype. The Date object is an example of this. Calling new Date() creates a new instance of Date with properties inheritied from its prototype but others that are set by the values you pass it. If you pass in a date string to Date then that instance of date will different than another instance you call by passing another date string to it. If you change a property of Date directly it’ll only be set for that specific instance but if you change or add a property to the Date object’s prototype then all instances of Date will inherit those properties.

Creating reusable objects with default values set

Utilizing the prototypes of objects will allow you to create new instances of objects that inherit the object prototype’s properties but also have their own direct props set on them for that single instance along. This is useful, for example, if you create an API library that needs to be set with an API token and you want to reuse that object without having to pass in your API credentials every time or have the ability to create multiple API clients using different credentials.

Practical Examples

So far all of this may be really hard to follow so I’ll give you a real world example. I recently had to create an API wrapper in Node.js for a remote API my new company had built. I needed users to be able to create a new instance of a client and then reuse it to make API calls without having to pass in the API credentials each time. Here’s how that’s done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Let's assume we create a Node module called
// 'myobject' from this.

function MyObject(apiKey) {
  // Return a new instance MyObject if not already instantiated
  if (!(this instanceof MyObject)) return new MyObject(apiKey);

  this.initialize(apiKey);
}

MyObject.prototype = {
  initialize: function(apiKey) {
      this.apiKey = apiKey;
  }

  showKey: function() {
      console.log(this.apiKey);
  }
};

module.exports = MyObject;

This very simple example of using an object’s prototype demonstrates how an object can have properties own by that instance of the object and those that are inherited from its prototype. The MyObject() function takes your API key as an argument and will set it internally. The initialize function is responsible for setting that property for each instance of the object. initialize gets called each time you call a new instance of MyObject. This is how you can have multiple instances of MyObject each with their own credentials. So let’s see how this works in practice. If you created a Node module with this code you can use it like so:

1
2
3
4
5
6
7
var MyObject = require('myobject');

var m = new MyObject('my-api-key');
var n = new MyObject('a-different-key');

m.showKey; // => my-api-key
n.showKey; // => a-different-key

The takeaway here is that by creating a new object prototype for our MyObject function we can have an initialize function that runs whenever we instantiate a new instance of the object that populates it with our API key. We can then call methods that are part of the MyObject’s prototype like showKey which will output the string you passed to that particular instance of the object.

So the next time you need to create a Node library that behaves similarly to what you get in object oriented languages like Ruby where you initialize an object with some properties by default you can use this technique. This only scratches the surface of what you can do.

Highlights, Web development

« Making Raw HTTP Requests in Node Simple API Authentication with Authorization Headers in Sinatra »

Comments