How to do encapsulation in JavaScript

November 03, 2015 0 Comments

How to do encapsulation in JavaScript

 

 

If you come from classical object-oriented languages like Java or C#, it might be a littler tricky to do encapsulation in JavaScript (hiding variables from the external scopes).

In this post we going to see tree ways to do encapsulation with JavaScript:

  1. IIFE (immediately Invoked Function Expression).
  2. Closures
  3. getters and setters Properties.
  4. The Revealing Module Pattern.

IIFE (immediately Invoked Function Expression)

First lets cover what an IIFE is:

In JavaScript we declare functions like this:

 function myFunc(){ console.log(myVar); // "Hello World" } 

And we call the function like this:

myFunc();

An IIFE is a combination of both in one, now, the more common and most used method to create an IIFE is with the parenthesis like this:

 (function myFunc(){ console.log("Hello World"); // "Hello World" })(); 

There are other ways to create IIFE, you can accomplish this by using any of the following operators: !, +, -, ~.

 !function myFunc(){ console.log("Hello World"); // "Hello World" }(); +function myFunc(){ console.log("Hello World"); // "Hello World" }(); -function myFunc(){ console.log("Hello World"); // "Hello World" }(); ~function myFunc(){ console.log("Hello World"); // "Hello World" }(); 

Closures:

In JavaScript a variable scope is defined by the curly braces { } of an expression, for example a function:

 function myFunc(){ var myVar = "Hello World"; } console.log(myVar) //undefined 

myVar is not defined outside of the { } of the function, now notice that you can access a variable defined in the outter scope, like this:

 var myVar = "Hello World"; function myFunc(){ console.log(myVar) // "Hello World" } 

With those two concepts you can encapsulate variables and remove it from the global scope and protect your data. This helps prevent variables and function declarations from living longer than expected in the global scope, which also helps avoid variable collisions. Also When your code is minified and bundled into a single file for deployment to a production, you could have collisions of  global variables. If you adopt to use IFFE in every JavaScript file, it will protects you against both of these by providing variable scope for each file.

book

Speaking JavaScript: An In-Depth Guide for Programmers
Like it or not, JavaScript is everywhere these days—from browser to server to mobile—and now you, too, need to learn the language or dive deeper than you have. This concise book guides you into and through JavaScript, written by a veteran programmer who once found himself in the same position.

Amazon

getters and setters Properties:

Why getters and setters can be used for encapsulation?
A: To limit access to an internal state of an object.

One of the advantages of properties is that you can have behavior in your fields, also limitate the field to be read only and/or write only.

 var myObj = { get myVar() { return 'Using get'; }, set myVar(value) { console.log('Using set, value: '+value); } }; 

Note: Up to IE 8, it doesn’t support get and set operators, instead you’ll have to use the __defineGetter__ and __defineSetter__ methods that can be found in Object.prototype.

 var myObj = { myVar1: 'Hello', myVar2: 'World' }; myObj.__defineGetter__('sayHello', function(){ return this.myVar1 + ' ' + this.myVar2; }); myObj.__defineSetter__('sayHello', function(value){ console.log(value); }); 

The Revealing Module Pattern

With this pattern we encapsulate and hide or reveal variable and functions in an object:

 var myRevealingModule = (function () { var privateCountVar = 0; function privateFunctionIncrement() { privateCountVar++; } function publicFunctionStart() { return privateFunctionIncrement(); } function publicGetCount(){ return privateCountVar; } function publicIncrement(){ return privateFunctionIncrement() } return { start: publicFunctionStart, increment: publicIncrement, count: publicGetCount }; })(); 

If you run the code above you’ll see that only the methods revealed in the return {…} are public see image below:

 return { start: publicFunctionStart, increment: publicIncrement, count: publicGetCount }; 

encapsulation revealing module pattern

Wrapping up

JavaScript is not an object oriented language, it is a functional language, but we can work around to have some of the goodies of the Object Oriented languages in JavaScript.

Those are some references for what in my opinion are two of the best JavaScript books I ever read (they are free):

http://speakingjs.com/es5/ 

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Thanks for reading :)


Tag cloud