Constructor Functions for [JS] Web Developers
Constructor Property Foursquare
Say it with me: there are no {classical inheritance} classes in JavaScript, only objects. However, the language does provide the tools necessary to create protective and extensible systems of creation and inheritance.
“The prototype is a property on a constructor function that sets what will become the __proto__ property on the constructed object.” -Peter Chang
Inheritance is enabled through prototypes, where fallback lookup objects can be added as a reference to an object’s prototype
key. This grants access to properties in the hierarchy, including that of each subsequently referenced object in the prototype in the chain. Constructor functions, hereafter referred to as constructors, are called with the new
keyword and return (yep) a new object. A constructor looks something like this:
function Plant(kind) { /* Initialize object */ }
And making an instance with the constructor:
var bush = new Plant(“bush”);
What the instance has access to (its API) defines whether a constructor property is public or private, and these can be defined in scope or out of scope.
function Plant() {
// In scope of the constructor's execution context
}
// Out of its scope
TL;DR: (1)use this.newProperty
in the constructor for individual-specific properties, (2)Constructor.prototype.newProperty
for generic methods, (3)store data with variables reference in the constructor if it should be obscured from the instances, and (4)create helper methods to reduce the initialization load and abstract away complexity.
Public Properties:
this (in-scope): when the new
keyword is invoked, another context is created with its own namespace, accessible in the constructor’s execution context through the this
keyword. A property can be attached to the instance by adding references to the new context through this
.
function Plant(type) {
this.type = type;
}
- Each time the constructor is called, these properties are created or referenced and attached to the instance’s
this
context, the new scope of the instance, on invocation. Consequently, this pattern is beneficial when a property should be instance-specific, as it should be given a scope to initialize after the constructor is invoked. - If every instance has the exact same property that will never be different depending on the individual, consider using prototype assignment instead of
this
.
.prototype (out of scope): over a class-based system, JavaScript utilized a prototype pattern to create an efficient system of inheritance. This is accomplished when a property is searched on an object by looking in the namespace referenced on the prototype key if not found in the current scope. The process continues until the property is first found or the prototype object is null. External to the scope of a constructor function, properties can be attached to the constructor’s prototype, which the instance then will inherit in its own prototype.
function Plant() { ... }
Plant.prototype.grow = function() {
// increase size
}
- These properties are accessible to every instance through the prototype chain, although the actual chain is abstracted from the developer, but you can read more about the fall-through lookup mechanics of the language here. The takeaway is that there is less space occupied as all of a constructors instances reference a single prototype object. This cuts down on both the space and time complexity of the algorithm by not requiring every instance to initialize the property, and in that no space is taken up in the instance by adding more to the prototype.
- Use if the property is static and all instances should have reliable access.

Private Properties:
Variables (in scope): when variables are declared within the constructor, the instance does not have direct access. These are often used only in the process of initialization to determine the return state of the instance. They can also be used to store data which can be accessed and manipulated in strictly defined ways exposed with public properties.
function Plant() {
// these 2 variables are inaccessible through the instance
var size = 0;
var grow = (rate) => {
size += rate;
console.log('Plant now :' + size + ' inches tall!');
}; // We can, however, attached a public method that
// does have access. Check your privilege:
this.startGrowing = (rate) => setInterval(e=>grow(rate), 1000);
}
- Privileged property: a special public methods that are 1) attached via this, and 2) that access these variables hidden in the instance namespace closure. Use these when you want to store a piece of data and control how the instance is allowed to read and manipulate it.
Helpers (out of scope): methods attached directly to the constructor function object’s namespace, are not inherited by instances. These should be used to reduce complexity in the initialization execution context by abstracting commonly used blocks of code into functions only accessible within that context. In other words, after that context has completed execution, there is no longer access to the constructor’s helper methods.
function Plant() {
var thorns = [];
this.newThorn = () => thorns.push({power: Plant.thornHelper});
this.countThorns = () => thorns.forEach(thorn => thorn.power());
}
Plant.thornHelper = function() {
console.log("Deals 1 point nature damage on contact");
};var roseBush = new Plant();
roseBush.newThorn();
roseBush.countThorns();
roseBush;
Below is a contrived example to help understand the mechanism. Oldsmobiles were the first automobile mass produced utilizing an assembly line technique; paving the way for the proliferation of productive factories. Thanks to these and other industrial ventures, the social stage was beginning to be set for the development several fundamental object oriented principles, namely abstraction and encapsulation.

It seems only fitting to learn the basic techniques of object creation by making some antique cars:
var Oldsmobile = function(year, color) {
// private variable properties:
var allowed = ['red', 'black', 'tan'];
var defaultColor = 'black';
// accessing helper method within constructor:
Oldsmobile.addAllowed(allowed, 'blue');
// privileged property (special public `this`):
this.color = allowed.find(newColor => newColor === color) ? color : defaultColor; // public `this` properties:
this.speed = 0;
this.drive = speed => this.speed = speed;
this.year = year;
};// public method:
Oldsmobile.prototype.customPaintjob = function(newColor){this.color = newColor};// helper method:
Oldsmobile.addAllowed = (colors, newColor) => colors.push(newColor);var myAntiqueCar = new Oldsmobile(1904, 'blue');
myAntiqueCar.drive(10);
myAntiqueCar.customPaintjob('orange');
myAntiqueCar;
Final thought: As it usually goes with interfaces offering various implementation patterns, each of these should be understood and utilized accordingly to maximize effectiveness as a developer.
Design Patterns for Web Developers series:
- Creational Patterns, inheritance, and Object Composition
- Singletons for Web Developers
- Constructor Functions for Web Developers
~It’s the end of the world. Every day is the end of the world. For some.~
Jacob
Shoutout to Robert Mennell for the info on classes and definitions. That’s right, he flippantly made my opening line less catchy with qualifiers. Thanks, Robert!
Thank you to Fredrik Folkeryd for pointing out a grammatical error.