OO In Javascript
The way object-oriented in JavaScript works can be hard to understand. By providing several options on how to use the prototypal-based object style, it can brings confusion and unnecessary complexity.
Here is the summary of my reading on JavaScript OO, mainly from JavaScript: The Good Parts, by Douglas Crockford. In hopes that it can help someone.
Types
Pseudo-Classical
This was added to JavaScript in order to simulate the classical class-object paradigm; which can look alien, but is the most used.
Prototypal
Native JavaScript object-orientation. No concept of class, just objects that share information. This is how prototypal object-orientation is meant to be used.
Functional
Based on prototypal, but more powerful. It adds security by isolating scopes and makes methods and variables private.
Characteristics and Uses
Pseudo-Classical
- Requires the ‘new’ declaration
- Start with a capital letter
- Uses prototype to define method
- Classical inheritance is nearly impossible
e.g.
var Transportation = function (type){ this.type = type; }; Transportation.prototype.getType = function () { return this.type; } var myBicycle = new Transportation("bicycle"); var Car = function(engineSound) { this.engineSound = engineSound; } Car.prototype = new Transportation(); Car.prototype.startEngine = function() { console.log(this.engineSound); } var myShinyCar = new Car("Vroum!!!...Vroum!!!"); myShinyCar.startEngine(); console.log(myShinyCar.type); // we lost the parent type 😦
Prototypal
The native JavaScript object system; less complex, but more powerful
- Uses {} to define a base object
- No concept of class, but copy from another object
- Inherit property of old object (also called differential inheritance)
e.g.
var transportationConstructor = { type : undefined, getType : function () { return this.type; } }; var Transportation = function (type){ this.type = type; }; Transportation.prototype = transportationConstructor; var myBicycle = new Transportation("bicycle"); var car = { type : 'Car', engineSound : 'Vrout!', startEngine : function () { console.log(this.engineSound); } } var Car = function(engineSound) { this.engineSound = engineSound; } Car.prototype = car; var myShinyCar = new Car("Vroum!!!...Vroum!!!"); myShinyCar.startEngine();
Functional
- Make variables and methods private
- Isolate the scope (same thing as module/closure)
- Enables the creation of durable object (no uses of this or that)
This means, that an object can’t be compromised by an attacker, the internal state will remain unchanged, and any modification to this/that will maintain the scope, instead of losing sight of this/that.
e.g.
var transportation = function(spec) { var that; // another private variable that = {} // or new Object() for pseudo-classical or another function constructor var getType = function () { return spec.type }; that.getType = getType; // enables another method called as a regular function, preventing this/that state-change return that; }; var myBicycle = transportation({ type : 'bicycle'}); var car = function (spec) { spec.type = 'Car'; var that = transportation(spec); var startEngine = function () { console.log(spec.engineSound); }; that.startEngine = startEngine; return that; } var myShinyCar = car({ engineSound : 'vroum!!! vroum!!!' }); myShinyCar.startEngine();