Object-oriented programming (OOP) is a programming paradigm (model/standard) based on the concept of “objects”, which can contain data, in the form of attributes / properties ), and code in the form of functions/procedures ( known as methods).
Objects are the main key/tool/means of OOP. We will try to explain this through example.
In order to create multiple of same structure we need object constructors. These can be made in few ways.
-
Prototype constructors are a JavaScript native way for creating objects that derive from a prototype.
-
Object prototype - constructor - is a function which serves as a blueprint and creates similar objects.
-
It also has it's own methods stored in the
prototype
property that it borrows to the objects it creates (it's children/instances).
This means that prototype serves as a blueprint for every object and it can also borrow its methods to those objects.
**ES5 Prototype Constructor - Example **
// Constructor names start with capital letter
function Car (brand, model) {
this.brand = brand;
this.model = model;
}
// Car.prototype = {}; - `prototype` property is created automatically by JS
var bmw = new Car ("BMW", "X5");
var lexus = new Car ("Lexus", "L300");
console.log(bmw); // Car {brand: "BMW", model: "X5"}
// Constructor names start with capital letter
function Car (brand, model) {
// this = {};
// this.__proto__ = Car.prototype;
this.brand = brand; // create property on the new instance
this.model = model;
// return this;
}
// keyword `new` makes the function a constructor, and points `this` to the new object
var bmw = new Car ("BMW", "X5");
var lexus = new Car ("Lexus", "L300");
console.log(bmw);
// Car {brand: "BMW", model: "X5", start: ƒ }
Note for the teacher - After this example you may refer to the slides to explain __proto__
function Car (brand, model) {
// this = {};
// this.__proto__ = Car.prototype;
this.brand = brand; // create property on the new instance
this.model = model;
// return this;
}
Car.prototype.start = function () {
console.log(this.brand + " start engine.");
};
// keyword `new` makes the function a constructor, and point `this` to a new object
var bmw = new Car ("BMW", "X5");
var lexus = new Car ("Lexus", "L300");
// Car {brand: "BMW", model: "X5" }
bmw.start();
console.log( bmw.__proto__ === Car.prototype );
console.log( lexus.__proto__ === Car.prototype );
Extending the constructor
// Extending the prototype constructor
function HybridCar (brand, model, engine) {
// this = {};
// this.__proto__ = Car.prototype;
// Calls Car and creates properties `brand` and `engineType `on the new instance
// ****
Car.call(this, brand, model);
// ****
this.engine = engine;
// return this;
}
// This extends the methods from the Car prototype onto HybridCar
// ****
HybridCar.prototype = Object.create(Car.prototype);
HybridCar.prototype.constructor = HybridCar;
// ****
// keyword `new` makes the function a constructor, and point `this` to a new object
var hybridBmw = new HybridCar ("BMW", "i3", "hybrid");
console.log(hybridBmw);
When object is created in JavaScript the engine adds the __proto__
(aka dunder proto) property to the new object. This __proto__
property points to the prototype
object of the it's constructor.
When a function is created in JavaScript the JS engine adds a prototype
object to the function.
This prototype
object has a constructor
property which points back to the function.