JavaScript is partly an object-oriented language.
To learn JavaScript, we got to learn the object-oriented parts of JavaScript.
In this article, we’ll look at some basic design patterns.
Class-Like Singleton
We can create a singleton object by storing the class instance in a global object.
For instance, we can write:
function Foo() {
if (typeof globalFoo === "undefined") {
globalFoo = this;
}
return globalFoo;
}
then we can create a Foo
instance by writing:
const a = new Foo();
const b = new Foo();
console.log(a === b);
And the console log should log true
since we store the existing instance in a global variable.
Then we returned it if it’s not undefined
.
Singleton Stored in the Property of the Constructor
We know we shouldn’t use global variables, so we can store the singleton instance as a property of the constructor instead.
Functions can have properties since they are objects.
So we can write:
function Foo() {
if (typeof Foo.instance === "undefined") {
Foo.instance = this;
}
return Foo.instance;
}
The only change is that we store the property in the instance instead of in a global variable.
We can also store it in a private property if we put it in a function.
So we can write:
const Foo = (() => {
let instance;
return function() {
if (typeof instance === "undefined") {
instance = this;
}
return instance;
}
})();
and do the same thing.
This way, we can’t accidentally change the instance to something else.
Factory Pattern
The factory pattern is creational design pattern.
It deals with creating objects.
The factory is a function that can help us create similar types of objects with one function.
For instance, we can create a function by writing:
const createElement = (type, url) => {
if (type === 'Image') {
return new Image(url);
}
if (type === 'Link') {
return new Link(url);
}
if (type === 'Text') {
return new Text(url);
}
}
We return the constructor instance based on the type
value.
And we also take the url
that’s used with the constructors.
Decorator Pattern
The decorator pattern is a structural pattern.
We can use this pattern to extend the functionality of objects.
With this pattern, we can extend an object’s functionality by picking the decorators that we want to apply to the object.
For instance, we can write:
function Person(name) {
this.name = name;
this.say = function() {
console.log(this.name);
};
}
function DecoratedPerson(person, street, city) {
this.person = person;
this.person = person.name;
this.street = street;
this.city = city;
this.say = function() {
console.log(this.name, this.street, this.city);
};
}
We have 2 constructors the Person
and DecoratedPerson
classes.
Person
is the class that we use as the base for the DecoratedPerson
class.
The DecoratedPerson
class adds extra properties on top of the Person
class.
This way, we keep the interface of DecoratedPerson
the same as the Person
constructor for the ones that come from Person
.
But we add more properties exclusive to the DecoratedPerson
class.
Conclusion
We can create singleton objects with a class like syntax.
The decorator pattern lets us extend the functionality of constructors.