Understand javascript encapsulation

  • 2021-01-03 20:50:27
  • OfStack

Encapsulation can be defined as hiding the internal data representation and implementation details of an object. Information hiding can be enforced through encapsulation.

In JavaScript, there is no keyword to declare private members, etc. So if you want to implement encapsulation/information hiding, you need to start from another idea. We can use the concept of closures to achieve encapsulation by creating methods and properties that are accessible only from within objects.

The basic way
In general, there are three ways to achieve the purpose of encapsulation.

Use this.XXX to declare a variable, and then declare getXXX, setXXX, and other methods of value and assignment.
Use this. _XXX to declare a variable, and then declare getXXX, setXXX, and other methods of value and assignment.
Use the concept of functional scope to do this.
1. Open doors


var Book = function(isbn,title,author){
 this.setIsbn(isbn);
 this.setTitle(title);
 this.setAuthor(author);
};

Book.prototype = {
 setIsbn: function(isbn){
  this.isbn = isbn;
 },
 getIsbn: function(){
  return this.isbn;
 },
 setTitle: function(title){
  this.title = title;
 },
 getTitle: function(){
  return this.title;
 },
 setAuthor: function(author){
  this.author = author;
 },
 getAuthor: function(){
  return this.author;
 }
};

Encapsulation is implemented using this approach, although accessors and assigns are implemented to protect private properties. In practice, however, private properties are still externally accessible, so encapsulation is essentially not implemented.

2. Use naming conventions for distinction


var Book = function(isbn,title,author){
 this.setIsbn(isbn);
 this.setTitle(title);
 this.setAuthor(author);
};

Book.prototype = {
 setIsbn: function(isbn){
  this._isbn = isbn;
 },
 getIsbn: function(){
  return this._isbn;
 },
 setTitle: function(title){
  this._title = title;
 },
 getTitle: function(){
  return this._title;
 },
 setAuthor: function(author){
  this._author = author;
 },
 getAuthor: function(){
  return this._author;
 }
};

Using this approach is similar to the first one, except that a different name is used to protect the use of private properties. However, in practical terms it still does not implement encapsulation.

3. Use function scope


var Book = function(newIsbn,newTitle,newAuthor){
 var isbn,title,author;

 this.setIsbn=function(newIsbn){
  isbn = newIsbn;
 };
 this.getIsbn=function(){
  return isbn;
 };
 this.setTitle=function(newTitle){
  title = newTitle;
 };
 this.getTitle=function(){
  return title;
 };
 this.setIsbn=function(newAuthor){
  author = newAuthor;
 };
 this.getIsbn=function(){
  return author;
 };
}

Because variables declared in JavaScript's functions are scoped, using this approach avoids direct external access to private properties. Basically achieve the required content of encapsulation.

Note here that we can use this.XXX and var to declare variables inside the function. The difference is that variables declared using ES42en.XXX are externally accessible. Variables declared using var are not directly accessible outside of a function because they are protected by the function scope.

4. Use distortion of function scope


var Book = (function(){
 // ... Other static methods 

 return function(newIsbn,newTitle,newAuthor){
  var isbn,title,author;

  this.setIsbn=function(newIsbn){
   isbn = newIsbn;
  };
  this.getIsbn=function(){
   return isbn;
  };
  this.setTitle=function(newTitle){
   title = newTitle;
  };
  this.getTitle=function(){
   return title;
  };
  this.setIsbn=function(newAuthor){
   author = newAuthor;
  };
  this.getIsbn=function(){
   return author;
  };
 };
})();

This method simply returns the execution of 1 constructor. And the constructor here is an inline function.

The advantage of this approach is that "only one copy will exist in memory. Because other static methods are declared outside the constructor, they are not privileged methods.

The rule for determining whether a method should be designed to be static is "Will this method access a private property?" If it does not, it would be more efficient to design it as a static method because it would only be created 1 copy.

constant
We can implement constants in a "only accessors, no assigns" manner.


// 1.
var Book = function(){
 var constants = ["key1": "1","key2": "2","key3": "3"];

 this.getConstant = function(key){
  return constants[key];
 };
};

Book.getConstant("key1");

// 2.
var Book = (function(){
 var constants = ["key1": "1","key2": "2","key3": "3"];

 var con = function(){};
 con.getConstant = function(name){
  return constants[name];
 };

 return con;
})();

Book.getConstant("key1");

The pros and cons
1, the place

Encapsulation protects the integrity of internal data;
Encapsulation makes object refactoring easier;
The coupling between modules is weakened to improve the reusability of objects.
Helps avoid namespace conflicts;
...
2, the shortcoming place

Private methods are difficult to test;
Having to deal with complex scope chain makes error scheduling more difficult;
Easy to form over-encapsulation;
JavaScript does not support encapsulation natively, so implementing encapsulation in JavaScript presents a complexity problem.

Above is the entire content of this article, I hope to help you with your study.


Related articles: