Object oriented programming in JavaScript
there are several layers to object-oriented programming in
JavaScript
OOP with single objects
Prototype chains
Constructors & Classes
Inheritance
SINGLE OBJECTS
objects are building blocks of JavaScript OOP and they are simple
maps from strings to values
properties
entries in the map
methods
properties whose values are functions
in which the this keyword refers to the receiver of the method call
object literal
var foobar = {
name: 'Foo',
surname: 'Bar',
getInfo: function () {
return this.name + ' ' + this.surname;
}
};
foobar.name //=> "Foo"
foobar.surename //=> "Bar"
foobar.getInfo(); //=> "Foo Bar"
foobar.name = 'Bar';
foobar.surname = 'Foo';
foobar.getInfo(); //=> "Bar Foo"
a few common patterns
- refactoring a switch/case statement
- holding constant strings
- etc.
sharing properties
it is easy to declare an object for a single person
but it becomes problematic when we have to add more persons
var fizzbuzz = {
name: 'Fizz',
surname: 'Buzz',
getInfo: function () {
return this.name + ' ' + this.surname;
}
};
problems with this approach
PROTOTYPE CHAINS
(delegation)
both objects share the same prototype object
both prototype chaning work like single objects
var Person = {
getInfo: function () {
return this.name + ' ' + this.surname;
}
};
var foobar = Object.create(Person);
foobar.name = 'Foo';
foobar.surname = 'Bar';
var fizzbuzz = Object.create(Person);
fizzbuzz.name = 'Fizz';
fizzbuzz.surname = 'Buzz';
foobar.getInfo(); //=> "Foo Bar"
fizzbuzz.getInfo(); //=> "Fizz Buzz"
ECMAScript 5 solution
var Person = {
getInfo: function () {
return this.name + ' ' + this.surname;
}
};
var foobar = {
__proto__: Person,
name: 'Far',
surname: 'Bar'
};
var fizzbuzz = {
__proto__: Person,
name: 'Fizz',
surname: 'Buzz'
};
foobar.getInfo(); //=> "Foo Bar"
fizzbuzz.getInfo(); //=> "Fizz Buzz"
ECMAScript 2015 solution
CONSTRUCTORS
function Person(name, surname) {
this.name = name;
this.surname = surname;
this.getInfo = function () {
return this.name + ' ' + this.surname;
};
};
var foobar = new Person('Foo', 'Bar');
var fizzbuzz = new Person('Fizz', 'Buzz');
foobar.getInfo(); //=> "Foo Bar"
fizzbuzz.getInfo(); //=> "Fizz Buzz"
a constructor function for Person
both instances have the getInfo() method
how do we remove this redundancy?
function Person(name, surname) {
this.name = name;
this.surname = surname;
};
Person.prototype.getInfo = function () {
return this.name + ' ' + this.surname;
};
var foobar = new Person('Foo', 'Bar');
var fizzbuzz = new Person('Fizz', 'Buzz');
foobar.getInfo(); //=> "Foo Bar"
fizzbuzz.getInfo(); //=> "Fizz Buzz"
sharing methods (delegation)
CLASSES (ES2015)
class Person {
constructor(name, surname) {
this.name = name;
this.surname = surname;
}
getInfo() {
return this.name + ' ' + this.surname;
}
}
var foobar = new Person('Foo', 'Bar');
var fizzbuzz = new Person('Fizz', 'Buzz');
foobar.getInfo(); //=> "Foo Bar"
fizzbuzz.getInfo(); //=> "Fizz Buzz"
a Person class
INHERITANCE
having in mind the Person constructor
our goal is to derive Employee from it
function Person(name, surname) {
this.name = name;
this.surname = surname;
};
Person.prototype.getInfo = function () {
return this.name + ' ' + this.surname;
};
function Employee(name, surname, department) {
Person.call(this, name, surname); // inherit instance properties
this.department = department; // create sub class specific properties
}
// Inherit Person.prototype properties
Employee.prototype = Object.create(Person.prototype);
// Override Person.prototype.getInfo method
Employee.prototype.getInfo = function () {
return Person.prototype.getInfo.call(this) + ' (' + this.department + ')';
};
var johnsmith = new Employee('John', 'Smith', 'IT Department');
johnsmith.getInfo(); //=> "John Smith (IT Department)"
using ECMAScript 2015 classes
class Person {
constructor(name, surname) {
this.name = name;
this.surname = surname;
}
getInfo() {
return this.name + ' ' + this.surname;
}
}
class Employee extends Person {
constructor(name, surname, department) {
super(name, surname); // inherit instance properties
this.department = department; // create sub class specific properties
}
getInfo() {
return super.getInfo() + ' (' + this.department + ')';
}
}
var johnsmith = new Employee('John', 'Smith', 'IT Department');
johnsmith.getInfo(); //=> "John Smith (IT Department)"
Day II: JavaScript - OOP
By Andrei Cacio
Day II: JavaScript - OOP
object creation, prototype chains & classes
- 1,400