Home  >  Article  >  Web Front-end  >  JavaScript Design Patterns Encapsulation and Information Hiding (Part 1)_Javascript Skills

JavaScript Design Patterns Encapsulation and Information Hiding (Part 1)_Javascript Skills

WBOY
WBOYOriginal
2016-05-16 17:51:321166browse

This article is divided into two parts. The upper part talks about basic patterns: full exposure, underline notation and using closures; the lower part talks about Advanced Patterns, how to implement static methods and properties, constants and other knowledge points. .
Encapsulation is a very basic and useful feature of object-oriented languages. Although JavaScript can also be called an object-oriented language, its support for encapsulation is not very good. Unlike other languages, as long as you use private and protected It can be achieved. But this does not mean that there is no way. Below I will introduce how to implement encapsulation in JavaScript.
1. Basic patterns, mainly includes three methods: full exposure method, underline notation method and using closure. (Closure is a very important and difficult concept. Friends who are interested can find information online. I have also reprinted other people's articles on my blog).
Here we take the book class as an example, and we need to create and initialize the book class.

Copy code The code is as follows:

// Book(isbn, title, author)
var theHobbit = new Book('0-395-07122-4', 'The Hobbit', 'J. R. R. Tolkien');
theHobbit.display(); // Outputs the data by creating and populating an HTML element.

1. Full exposure method:
Creating the book class can use the most traditional constructor method,
Copy code The code is as follows:

var Book = function(isbn, title, author) {
 if(!this.checkIsbn(isbn)) throw new Error('Book: Invalid ISBN.');
 this.isbn = isbn;
 //The function of || in the code is that if title has no value, 'No title specified' will be assigned to this.title. This method is very useful and you can use it in your own code.
 this.title = title || 'No title specified';
 this.author = author || 'No author specified';
}
Book.prototype = {
 //Verification isbn function
checkIsbn: function(isbn) {
},
//Set isbn
setIsbn: function(isbn) {
if(!this.checkIsbn(isbn)) throw new Error('Book: Invalid ISBN.');
this. isbn = isbn;
 },
// Get title
getTitle: function() {
return this.title;
},
// Set title
setTitle: function(title) {
 this.title = title || 'No title specified';
 },
 //Get the author
 getAuthor: function() {
 return this.author;
 },
 //Set the author
 setAuthor: function(author) {
 this.author = author || 'No author specified';
 },
 //Display function
 display: function() {
  ...
 }
};


There is a lot of code, I will briefly explain it here. Creating classes in JavaScript is a bit different from C# and Java. C# and Java will wrap all methods and attributes in a class file, for example



Copy code
The code is as follows: public class book() { private string isbn;
public string ISBN
{
set
{
  this.isbn=value; (string isdn)
{
......
}
......
public void Display()
{
.... .
}
}


Javascript can also use this method, but it is recommended to use the method I used above to define the attributes into the class definition function (or constructor) and the method into the prototype object. This approach has better performance. As for the reason, you can Go to google.
The function that the above js code wants to achieve is to define a book class, which includes three private variables (or attributes) isbn, title, author, a private method checkIsbn, and several public methods getIsdn, setIsdn,. ..display. The idea is good, but the reality is cruel. In fact, those private properties or methods are not private at all. For example, theHobbit.isbn = '978-0261103283'; You can assign a value to isbn in this way without error and absolutely successful. The reason is that JavaScript has no private way to privatize specific objects. In addition, this implementation method can also cause confusion when using it. What properties and methods does the creator of the class want to expose? The first improvement method is introduced below, the underline marking method.
 2. Underline notation:
Copy code The code is as follows:

var Book = function(isbn, title, author) {
// Constructor code.
this.setIsbn(isbn);
this.setTitle(title);
this.setAuthor(author);
}
Book.prototype = {  
 //Verify isbn function
 _checkIsbn: function(isbn) {
  ... function() { return this._isbn;
},
//Set isbn
setIsbn: function(isbn) { ('Book: Invalid ISBN.'); This._isbn = isbn;
},
...
display: function() { . ..  
 }
};


In fact, just add an underscore _ in front of all properties or methods that you want to implement privately, and there is no other operation. This method does not achieve true privatization. theHobbit._isbn = '978-0261103283'; This operation is still successful. The greatest significance of this method is to tell the users of the class which objects the author intends to expose and which ones he does not want to expose. . But the author has no control over whether users follow the author's ideas.
So is there a way to achieve true privatization? The answer is yes, it is to use closures.
3. Use closures:
The reason why JavaScript can achieve true encapsulation is inseparable from its unique function scope, function support for internal functions, and closures. You can go online to collect relevant knowledge to deepen your understanding.
The first thing I will talk about below is the function scope. In JavaScript, if a variable is defined inside a function, there is no way to access it from outside the function. In fact, implementing private properties or methods in JavaScript takes advantage of this special property. Example:



Copy code


The code is as follows:
function foo() {  var a = 10; Function bar() { a *= 2; } bar();
return a;
}


in In the above example, function foo defines variable a and method bar internally. A and bar cannot be accessed from outside foo, but because a and bar are both defined inside foo, bar can access a. So is there a way to access bar outside foo? The answer is yes, it is to use a closure.




Copy code

The code is as follows:
function foo() {  var a = 10 ; Function bar() { a *= 2; return a; }
return bar;
}
var baz = foo(); // baz is now a reference to function bar.
baz(); // returns 20.
baz(); // returns 40.
baz(); // returns 80.
var blat = foo(); // blat is another reference to bar.
blat(); // returns 20, because a new copy of a is being used.


This is what was mentioned earlier JavaScript functions support internal functions. The internal function bar can access the private variable a, and the function foo throws the internal function bar to baz, and baz can access the internal variable a, which implements closure. Everyone will understand at a glance. In this way, private variables and methods are actually implemented. Returning to our previous book example, the implementation is as follows:




Copy the code

The code is as follows:

var Book = function(newIsbn, newTitle, newAuthor) {
  // implements Publication
  // Private attributes.
  var isbn, title, author;
  // Private method.
  function checkIsbn(isbn) {
    ...
  }
  // Privileged methods.
  this.getIsbn = function() {
    return isbn;
  };
  this.setIsbn = function(newIsbn) {
    if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');
    isbn = newIsbn;
  };
  this.getTitle = function() {
    return title;
  };
  this.setTitle = function(newTitle) {
    title = newTitle || 'No title specified';
  };
  this.getAuthor = function() {
    return author;
  };
  this.setAuthor = function(newAuthor) {
    author = newAuthor || 'No author specified';
  };
  // Constructor code.
  this.setIsbn(newIsbn);
  this.setTitle(newTitle);
  this.setAuthor(newAuthor);
};
// Public, non-privileged methods.
Book.prototype = {
  display: function() {
    ...
  }
};

上述代码就实现了 isbn, title, author和checkIsbn的私有化,外部是决定不能直接访问到的。如需访问 isbn, title, author只能通过对象级的方法getTitle,setTitle...。比如要给isbn赋值,只能用theHobbit.setIsbn = '978-0261103283';,如果你还用theHobbit._isbn = '978-0261103283';,对不起要报错了。

 好了,今天的内容就讲到这里了,希望对大家有帮助。
作者:下一站永远

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn