All the OOP
ES5 Edition
ES5 vs. ES6
If you remember anything about the differences between ES5 & ES6 OOP be it this:
- In ES6 we use the keyword class to define our classes, in ES5 we use the function keyword.
- In ES6 we have a constructor method for the construction of each instance of our objects, in ES5 any code we have in our main function block is used.
- In ES6 we have getters/setters, in ES5 we use the this context of the object(function).
- In ES6 we have "true" inheritance. In ES5 we have prototypal inheritance.
ES5 vs. ES6
Defining a class and it's constructor
//this is just a function
function PurchaseOrder(){
// However, it will have special behavior when
// INVOKED with the new keyword in that it
// RETURNS itself as a unique object reference.
//this is 'constructor' code
this.name = 'Bulk Cheetos';
}
// proper usage
var order = new PurchaseOrder();
console.log(order.name) // 'Bulk Cheetos'
// this is "allowed"
var order = PurchaseOrder(); //undefined
console.log(order.name); // Error
ES5
ES6
// It doesn't "look" like a function
class PurchaseOrder{
//explicit constructor logic called
//when instantiated with new
constructor(){
this.name = 'Bulk Cheetos'
}
}
var order = new PurchaseOrder();
console.log(order.name); // 'Bulk Cheetos'
//this is NOT allowed
var order = PurchaseOrder();
//TypeError: Classes can’t be function-called
*Class definitions are not hoisted
ES5 vs. ES6
Defining properties of a class
//this is just a function
function PurchaseOrder(){
//this is 'constructor' code
var name = 'Bulk Cheetos';
this.name = function(){
return name;
}
}
// proper usage
var order = new PurchaseOrder();
order.name(); // 'Bulk Cheetos'
ES5
ES6
// It doesn't "look" like a function
class PurchaseOrder{
constructor(){
this.name = 'Bulk Cheetos'
}
get name(){
return this.name;
}
set name(val){
this.name = val;
}
}
var order = new PurchaseOrder();
order.name; // 'Bulk Cheetos'
ES5 vs. ES6
Defining methods of a class
//this is just a function
function PurchaseOrder(){
//this is 'constructor' code
var name = 'Bulk Cheetos';
this.print = function(){
console.log('Printing....');
};
}
// proper usage
var order = new PurchaseOrder();
order.print(); // 'Printing...'
ES5
ES6
// It doesn't "look" like a function
class PurchaseOrder{
constructor(){
this.name = 'Bulk Cheetos'
}
print(){
console.log('Printing...');
}
}
var order = new PurchaseOrder();
order.print(); // 'Printing...'
ES5 vs. ES6
Inheritance
//this is just a function
function Order(){
this.id = 'HH244';
}
Order.prototype.print = function(){
console.log('Printing....');
};
function PurchaseOrder(){
Order.call(this);
this.name = 'Bulk Cheetos';
}
PurchaseOrder.prototype =
Object.create(Order.prototype, {
constructor: {
value: PurchaseOrder
}
});
ES5
ES6
// It doesn't "look" like a function
class Order{
constructor(){
this.id = 'AA2245';
}
print(){
console.log('Printing...');
}
}
class PurchaseOrder extends Order{
constructor(){
this.name = 'Bulk Cheetos'
}
}
ES5
Overriding a super constructor
(don't use super constructor)
Constructor Overloading
//this is just a function
function Order(){
this.id = 'HH244';
}
Order.prototype.print = function(){
console.log('Printing....');
};
function PurchaseOrder(){
//Order.call(this); //Don't invoke the super constructor
this.name = 'Bulk Cheetos';
}
PurchaseOrder.prototype =
Object.create(Order.prototype, {
constructor: {
value: PurchaseOrder
}
});
//PurchaseOrder will still have the print method but no 'id' property
//PurchaseOrder will have any methods defined on the prototype
//this is just a function
function Order(){
this.id = 'HH244';
}
Order.prototype.print = function(){
console.log('Not implemented');
}
function PurchaseOrder(){
Order.call(this);
this.name = 'Bulk Cheetos';
}
PurchaseOrder.prototype =
Object.create(Order.prototype, {
constructor: {
value: PurchaseOrder
}
});
PurchaseOrder.prototype.print = function(){
console.log('Printing to laser printer');
}
ES5
Overriding a super method
(Don't use that one, use this one)
Method Overriding
function Order(){
this.id = 'HH244';
}
Order.prototype.print = function(){
console.log('Checking paper...');
}
function PurchaseOrder(){
Order.call(this);
this.name = 'Bulk Cheetos';
}
PurchaseOrder.prototype =
Object.create(Order.prototype, {
constructor: {
value: PurchaseOrder
}
});
PurchaseOrder.prototype.print = function(){
Order.prototype.print.call(this);
console.log('Printing to laser printer');
}
var order = new PurchaseOrder();
order.print();
//'Checking paper...'
//'Printing to laser printer'
ES5
Extending a super method
Method Extension
function Order(){
var id = 'BB3445';
Object.defineProperty(this, "id", {
get: function(){
return id;
},
set: function(val){
id = val;
},
enumerable: true, //does this show up when inspecting properties
configurable: false, // don't allow this property to be removed from object instances
writable: true //allow this property to be modified, default is false when using defineProperty
});
}
function PurchaseOrder(){} //Define our class
//Inherit from Order by setting prototype and constructor
PurchaseOrder.prototype = new Object(Order.prototype, {
constructor: {
value: PurchaseOrder,
configurable: true,
enumerable: true,
writable: true
}
});
//You will sometimes see this. Yuck.
PurchaseOrder.prototype = new Order(); //prototype inherits functionality
//constructor is a reference to what was used to create, otherwise the constructor of PurchaseOrder is Object
PurchaseOrder.prototype.constructor = PurchaseOrder;
Even Better Object Definition
function PurchaseOrder(){
var id = 'BB3445';
Object.defineProperty(this, "id", {
get: function(){
return id;
},
set: function(val){
id = val;
},
enumerable: true,
configurable: true
});
}
PurchaseOrder.prototype = {
constructor: Order, //DO NOT FORGET TO DO THIS IF YOU USE THIS PATTERN
print : function(){
console.log('Checking paper...');
},
ship : function(){
console.log('Send to place...');
}
}
Another way to use prototype
The constructor is defined on the prototype. Not the function.
Comparing Types of Objects
function Order(){
var id = 'BB3445';
Object.defineProperty(this, "id", {
get: function(){
return id;
},
set: function(val){
id = val;
}
});
}
function PurchaseOrder(){} //Define our class
PurchaseOrder.prototype = new Object(Order.prototype, {
constructor: {
value: Order
}
});
//You will sometimes see this. Yuck.
PurchaseOrder.prototype = new Order(); //prototype inherits functionality
console.log(order instanceof PurchaseOrder) //true
console.log(order instanceof Order) //true
console.log(typeof order) //function, still just a function
use instanceof for comparison not typeof
Things to Remember:
- All Object inherit from Object.prototype
- Methods defined in the constructor are copied to each new instance
- Prototype methods have one copy shared among all instances
- Adding a prototype method at any point will add that method to ALL current/future instances of that object
- Private variables should be in your constructor, not the prototype
All the OOP - ES5 Edition
By Jason Sewell
All the OOP - ES5 Edition
The basics of ES5 OOP and basic usage of prototypes.
- 2,704