You are on page 1of 13

JavaScript Patterns

What is a Pattern?

✤ A re-usable solution that can be applied to occurring


problems in software design (JavaScript Applications)

✤ Can also be thought of as programming templates

✤ Situations vary significantly


Module Pattern

✤ Modules are an integral piece of any robust


application's architecture and typically help in
keeping the units of code for a project both cleanly
separated and organised.
Module Pattern

✤ Modules are an integral piece of any robust


application's architecture and typically help in
keeping the units of code for a project both cleanly
separated and organised.
(function() {

// declare private variables and/or functions

return {
// declare public variables and/or functions
}

})();

var HTMLChanger = (function() {


var contents = 'Hello HTML Changer'

var changeHTML = function() {


var element = document.querySelector('h1');
element.innerHTML = contents;
}

return {
callChangeHTML: function() {
changeHTML();
console.log(contents);
}
};

})();

HTMLChanger.callChangeHTML(); // Outputs: 'Hello HTML Changer'


console.log(HTMLChanger.contents); // undefined
Revealing Module Pattern

✤ A variation of the module pattern is called


the Revealing Module Pattern. 
(function() {

// declare private variables and/or functions

return {
// declare public variables and/or functions
}

})();

var HTMLChanger = (function() {


var contents = 'contents'

var changeHTML = function() {


var element = document.getElementById('attribute-to-change');
element.innerHTML = contents;
}

return {
changeHTML: changeHTML
};

})();

HTMLChanger.callChangeHTML(); // Outputs: 'contents'


console.log(HTMLChanger.contents); // undefined
Singleton Pattern

✤ A Singleton only allows for a single instantiation, but


many instances of the same object. The Singleton
restricts clients from creating multiple objects, after the
first object created, it will return instances of itself.
const Singleton = (function(){
let instance

function createInstance() {
const object = new Object({name: "Brad"})
return object
}

return {
getInstance: function() {
if(!instance){
instance = createInstance();
}

return instance
}
}
})()

const instanceA = Singleton.getInstance()


const instanceB = Singleton.getInstance()

console.log(instanceA === instanceB)


Observer Pattern

✤ Define a one-to-many dependency between objects so


that when one object changes state, all its dependents
are notified and updated automatically.

✤ The Observer pattern offers a subscription model in


which objects subscribe to an event and get notified
when the event occurs. 
class EventObserver {
constructor() {
this.observers = []
}

subscribe(fn) {
this.observers.push(fn)
console.log(`You are now subscribed to ${fn.name}`)
}

unsubscribe(fn) {
this.observers = this.observers.filter( item => item !== fn )
console.log(`You are now unsubscribed from ${fn.name}`)
}

fire() {
this.observers.forEach( fn => fn() )
}
}

const getDate = () => console.log(`Date: ${new Date()}`)

document.querySelector('#subscribe').addEventListener( 'click', () => {


MyObserver.subscribe(getDate);
})

document.querySelector('#unsubscribe').addEventListener( 'click', () => {


MyObserver.unsubscribe(getDate);
})

document.querySelector('#fire').addEventListener( 'click', () => {


MyObserver.fire();
})
Prototype Pattern

✤ The Prototype design pattern relies on the JavaScript prototypical


inheritance.

✤ https://developer.mozilla.org/en-US/docs/Web/JavaScript/
Inheritance_and_the_prototype_chain

✤ When it comes to inheritance, JavaScript only has one construct:


objects. Each object has a private property which holds a link to
another object called its prototype. That prototype object has a
prototype of its own, and so on until an object is reached
with null as its prototype. By definition, null has no prototype,
and acts as the final link in this prototype chain.
// Let's create an object o from function f with its own properties a and b:
let f = function () {
this.a = 1;
this.b = 2;
}
let o = new f(); // {a: 1, b: 2}

// add properties in f function's prototype


f.prototype.b = 3;
f.prototype.c = 4;

// do not set the prototype f.prototype = {b:3,c:4}; this will break the prototype chain
// o.[[Prototype]] has properties b and c.
// o.[[Prototype]].[[Prototype]] is Object.prototype.
// Finally, o.[[Prototype]].[[Prototype]].[[Prototype]] is null.
// This is the end of the prototype chain, as null, by definition, has no [[Prototype]].
// Thus, the full prototype chain looks like:
// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null

console.log(o.a); // 1
// Is there an 'a' own property on o? Yes, and its value is 1.

console.log(o.b); // 2
// Is there a 'b' own property on o? Yes, and its value is 2.
// The prototype also has a 'b' property, but it's not visited.
// This is called Property Shadowing

console.log(o.c); // 4
// Is there a 'c' own property on o? No, check its prototype.
// Is there a 'c' own property on o.[[Prototype]]? Yes, its value is 4.

console.log(o.d); // undefined
// Is there a 'd' own property on o? No, check its prototype.
// Is there a 'd' own property on o.[[Prototype]]? No, check its prototype.
// o.[[Prototype]].[[Prototype]] is Object.prototype and there is no 'd' property by default, check its prototype.
// o.[[Prototype]].[[Prototype]].[[Prototype]] is null, stop searching,
// no property found, return undefined.

You might also like