Pages

Saturday, October 1, 2016

Objects That Age (JavaScript)

JavaScript provides several standard built-in objects, one of which is the Date object. In the JavaScript code below, the standard Date object is used as a constructor to produce instances of Data objects. Another standard object used implicitly in the code below is the Object object. (Be sure to follow the hyperlinks in the previous sentences and become familiar with the Date and Object objects.)

As demonstrated in Objects With Eyes (JavaScript), an object with a property called createDate can be created like this:
{ createDate: new Date() }
The same object can be created in two steps, using a variable called 'x' to hold the value of the object, like this:
var x = {};
x.createDate = new Date();
The same object can also be created using a constructor function like this:
function ObjectThatAges() { this.createDate = new Date(); }
new ObjectThatAges();
By default, objects created by constructor functions have a property called __proto__. Also by default, the value of a newly created object's __proto__ property is initially set to the value of Object.prototype, which itself is a standard build-in object. We can override the latter JavaScript behavior by specifying an object to be used instead of Object.prototype. Given the constructor ObjectThatAges above, for example, we can define a property called ObjectThatAges.prototype. If this property has been defined and is set to the value of a non-null object prior to calling the ObjectThatAges constructor, then its value will be used to initialize the value of the __proto__ property of all objects created by invoking the constructor.

For example, we can define an object with a method called ageInMs (where Ms stands for milliseconds) that will be used to initialized the __proto__ property of instances of objects created by the ObjectThatAges constructor like this:
ObjectThatAges.prototype = {
  ageInMs: function() {
    return new Date() - this.createDate;
  }
};
Putting some of the pieces above together, we can defining our constructor and its prototype value, create a new object using the constructor, and then call the object's ageInMs method like this:
function ObjectThatAges() {
  this.createDate = new Date();
}
ObjectThatAges.prototype = {
  ageInMs: function() {
    return new Date() - this.createDate;
  }
};
var x = new ObjectThatAges();
x.ageInMs();
Subsequently, we can call the ageInMs method again and again to find out how much time has elapsed since a particular object was created as shown in the following image.

Remember that JavaScript objects created by a constructor may have distinct property values (e.g. eyeColor and createDate in the cases of ObjectWithEyes and ObjectThatAges respectively) and that those property values may or may not need to be passed as argument values to a constructor defined in terms of one or more parameters. However, all JavaScript objects created by a given constructor “inherit” the same prototype value. Hence properties that distinguish one instance of an object from another may be initialized from within the body of a constructor function while properties, such as methods and constant values, that are common to an entire “class” of objects may be associated with the object serving as the value of a constructor's prototype property.

Think about ways you could use objects constructed by ObjectThatAges. Ponder the following code snippet, for example.
var first = new ObjectThatAges();
var last = new ObjectThatAges();
for (var i=0; i<1000000; i++) {
  last = new ObjectThatAges();
}
var ageOfFirst = first.ageInMs();
var ageOfLast = last.ageInMs();
console.log(ageOfFirst);
console.log(ageOfLast);