This article describes OOP (methods of encapsulation, polymorphism and inheritance) in JavaScript. We will review two approaches to build it (with prototypes and without). Also I will show how to build a class factory. So, let's get started 1. OOP building with “Prototypes” At first we need to have an object…
function Button(name) { // Creating class Button
this.name = name; // Adding property “name” to class Button
}
button = new Button(‘A’); // Initialization an object
Now we need to create a child to show inheritance. We will do it with property “prototype”.
function MobileButton(name) { // Creating child class which will be inherited from class Button
this.name = name;
}
MobileButton.prototype = button;
mobileButton = new MobileButton(‘B’); // So the link on prototype is created by operator new.
Now I will show how to implement inheritance where class is used instead of object:
function Button(name) { // Creating class Button
this.name = name; // Adding property “name” to class Button
}
Button.prototype.clickOnMe = function () { // Adding method ”clickOnMe” to class Button
alert(“Clicked”);
}
function MobileButon(name) { // Creating class MobileButton
Button.apply(this, arguments); // We call parent constructor, inherit his members
}
MobileButton.prototype = new Button(); // Inheriting MobileButton from class Button
So methods, as we see, are stored in the prototype. In code below we will show how to implement polymorphism with prototypes:
…
MobileButton.prototype.clickOnMe = function() {
Button.prototype.clickOnMe.apply(this, arguments); // Calling parent method if it is needed
alert(‘Phone button has been clicked’); // Custom implementation for “clickOnMe” function
}
In code above we see that we call parent method “clickOnMe” from class prototype; Encapsulation:
function Button(name) {
this.name = name;
}
Button.prototype._protectedClick = function() { // But name with “_” it is just agreement
alert(‘Click’);
}
Button.prototype.click = function () {
this._protectedClick();
}
2. OOP building without “Prototypes” The logic of work without prototypes is the same, but you will notice that initialization of methods is in constructor. So here is an example:
function Button(name) {
this.name = name; // Creating public property of class Button
this.clickOnMe = function() { // Creating the method of class Button
alert(‘Click’);
}
}
function MobileButton(name) {
Button.apply(this, arguments); // Calling parent constructor (clickOnMe will be present) So we inherit MobileButton class from Button one
this.doubleClick = function () { // Creating child custom method
alert(‘Double click’);
}
}
Encapsulation without prototypes can be implemented in initialization of variables and methods inside constructor and if you want to make method or action public you need to set link of the current object for this method or property, example:
function Button(name) {
self = this;
var privateVariable = 7;
function show() { // Private method but with “showPublic” we make it as public
self.method();
}
self.showPublic = show; // Setting link in current object for “show” method
}
Polymorphism without “Prototypes” can be implemented by overriding link for parent method from the child. Let’s take a look:
function MobileButton(name) {
Button.apply(this, arguments); // Calling parent constructor.
var parentShowMethod = this.showPublic; // We get link on parent method
this.showPublic = function() { // Overriding parent method
parentShowMethod.call(this); // Calling parent’s method
alert(‘Custom alert message from child method which will be called after parent’);
}
}
3. Class factory Now at the end let me show you how to create class factory in JavaScript:
var button = Button(‘B’);
button.clickOnMe();
function Button(name) {
var privateMember = 1;
function privateClick() { // Private member. We don’t have access for it outside class
alert(‘We call private method’);
}
return {
publicClick: function() { // Public member
alert(“Public method”);
privateClick ();
}
}
}
Inheritance and polymorphism in class factory:
function MobileButton(name) {
var mobileButton = Button(name); // We inherit MobileButton from Button
mobileButton.publicClick = function() { // We override “publicClick” parent’s method
alert(‘Overridden method);
}
}
Summary: So OOP with prototypes: 1) Works faster; 2) Doesn’t take a lot of memory; 3) Works with “instanceof” statement (tests if an object is of a particular type. It evaluates to true if the object is that type and false if it is not. Instance of is a reserved word and cannot be used for anything else but testing the object's type). Benefits of method without prototypes: 1) Can create private members (properties and functions); My point of view is that the first method is better, because it works faster and looks more reliable as good code structure. But benefits of method without prototype are also important, for example if we don’t want to rely only on agreements for JavaScript (i.e. _protectedMethod). Benefits of class factory: Class factory is very similar on “OOP without prototypes” but looks much better and we don’t need to put additional word “new” when we create an object. i.e. button1 = Button(‘b’). And structure of code is much better. But general performance is less than in “OOP with prototypes”. Sergey K., .NET team, Binary Studio