JavaScript template design: difference between module template and module template expansion?

I’ve been reading the Learning JavaScript Templates book recently. What I am not getting is the difference between the module template and the expansion of the module template. I feel that they are one and the same. Can anyone give an example?

+51
javascript design design-patterns module-pattern revealing-module-pattern
Apr 07
source share
3 answers

There are at least three different ways to implement a module template, but the drop-down module template is the only descendant of a module that has an official name.

Base module template

The module template should satisfy the following:

  • Private members live in closure.
  • Open items are displayed in the returned object.

But there is a lot of uncertainty in this definition. By eliminating ambiguity in different ways, you get module template options.

Expand Module Template

The drop-down module template is the most famous and most popular of the module options. It has several advantages over other alternatives, such as

  • Rename public functions without changing the function body.
  • Change of members from public access to private or vice versa by changing one line without changing the body of the function.

RMP meets three additional conditions in addition to the original:

  • All members, whether public or private, are determined at closing time.
  • The returned object is an object literal without function definitions. All right expressions are trailing variables
  • All references are associated with closure variables, not with the return object.

The following example shows how it is used.

var welcomeModule = (function(){ var name = "John"; var hello = function(){ console.log("Hello, " + name + "!");} var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");} return { name: name, sayHello: hello, sayWelcome: welcome } })(); 

If you want to make private name and sayHello private, you just need to comment out the corresponding lines in the returned object.

 var welcomeModule = (function(){ var name = "John"; var hello = function(){ console.log("Hello, " + name + "!");} var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");} return { //name: name, //sayHello: hello, sayWelcome: welcome } })(); 

Conditional Literal Module Template

This is probably the oldest version of the module template. Unlike RMP, there is no official official name for this option.

In addition to the original, it satisfies the following conditions:

  • Private members are identified at closing.
  • Public items are defined in the literal of the returned object.
  • Links to public users are available at this whenever possible.

In the following example, you can see how, unlike RMP, function definitions are actually in the literal return object, and member references are in this .

 var welcomeModule = (function(){ return { name: "John", sayHello: function(){ console.log("Hello, " + this.name + "!");} sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");} } })(); 

Note that unlocking RMP to make name and sayHello private, links pointing to name and sayHello in various function body definitions must also be changed.

 var welcomeModule = (function(){ var name: "John"; var sayHello = function(){ console.log("Hello, " + name + "!");}; return { //name: "John", //sayHello: function(){ console.log("Hello, " + this.name + "!");} sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");} } })(); 

Module template with return object stub

This option also does not have an official name.

In addition to the original, it satisfies the following conditions:

  • An empty empty object is returned at the beginning.
  • Private members are identified at closing.
  • Public members are defined as stub members
  • Links to public elements through a stub object

Using our old example, you can see that public elements are directly added to the stub object.

 var welcomeModule = (function(){ var stub = {}; stub.name = "John"; stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");} stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");} return stub; })(); 

If you want to make private name and sayHello private, as before, member links now-private must be changed.

 var welcomeModule = (function(){ var stub = {}; var name = "John"; var sayHello = function(){ console.log("Hello, " + name + "!");} stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");} return stub; })(); 

Summary

The differences between the drop-down module template and the other variations of the module template are mainly related to how public members refer. As a result, RMP is much easier to use and modify, which explains its popularity. However, these advantages bring a huge price (in my opinion), which is mentioned by addy Osmani in his post in the disclosure of the module template ,

The disadvantage of this template is that if a private function refers to a public function, this public function cannot be overridden if a patch is required. This is because the private function will continue to refer to the private implementation, and the template does not apply to public members, but only to functions.

Elements of public objects that reference private variables are also subject to rule notes without corrections above.

As a result, modules created using the Revealing Module template may be more fragile than those created using the original module template, so care should be taken during use.

and which I talked about in some other posts .

+96
Apr 7 '14 at 16:55
source share

Just try to do something based on the response to the top comment. Maybe it is safer if you call a private function, passing it to it, so a private function can refer to a public function with this variable.

I created an expansion module with the following code.

 var HTMLChanger = (function () { var privateFunc = function () { this.sayHello(); } var hello = function () { console.log('say Hello'); } var callPrivate = function () { privateFunc.call(this); } return { sayHello: hello, callPrivate: callPrivate }; })(); HTMLChanger.callPrivate(); //say Hello HTMLChanger.sayHello = function() { console.log('say Hi!') }; HTMLChanger.callPrivate(); //say Hi! 

As you can see, we can override the open item.

0
Feb 17 '18 at 6:30
source share

The short answer. In the module module, we define the functions in the returned object.

In the Revealing Module template, we define functions in the closing area and use only the variable names in the returned object.

This simplifies the code and has many other benefits.

0
Jun 05 '18 at 3:13
source share



All Articles