how to use the javascript module pattern in a real example?

后端 未结 5 1924
陌清茗
陌清茗 2021-01-31 05:59

I am trying to understand the JavaScript Module Pattern. I\'ve seen examples of what it should look like, but I don\'t understand how to use it.

For example, a few thing

相关标签:
5条回答
  • 2021-01-31 06:39

    This is quite an opinionated subject, but I'd do it (without entirely knowing your full app and what it does), somewhat like so:

    var myApp = (function() {
    
      var someElement = $("#foo"); //some element I know I'll use lots
    
      var addMessage = function(message) {
        $.ajax({
          url: '/test',
          type: 'POST',
          dataType: "json",
          data: {'message' : message},
          success: function(data) {
                  ...
          },
          error: function() {
              ...
          }
        });
      };
    
      var inputClick = function(event) {
        event.preventDefault();
        //depending on if you'll reuse these selectors throughout the app I might have these as variables
        $('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');
    
        var message = $(".wallmessage").val();
    
        if (message == ""){
          $("#messageempty").jmNotify();
          $('.remove_loading').remove();
        } else {
          addMessage(message);
        }
      };
    
      var bindFunctions = function() {
        $("input#share").on("click", inputClick)
      };
    
      var init = function() {
        bindFunctions();
      };
    
      return {
        // EDIT: 27/12/16 - need to return init for 'usage' example to work
        init: init,
        addMessage: addMessage
        //anything else you want available
        //through myApp.function()
        //or expose variables here too
      };
    
    
    })();
    
    //usage
    
    myApp.init();
    

    Your original code for the pattern is wrong, the function has to have () at the very end, to make it a function that is immediately invoked, and then executes, exposing anything through the return statement.

    You may wish to differ slightly from what I've done, it's only a basic idea but I hope it might get you started.

    Someone a while back asked a question relating to this pattern and I answered it explaining why we use (function() {})(); and how the return statement works in that context, if you're slightly confused by it that might be worth reading too.

    0 讨论(0)
  • 2021-01-31 06:42

    The idea is to cut down the visibility from outside world and better code management by dividing your code into segments/modules.Check this out if you want to see a really good usage of modular design pattern and some way of how we can get benefit from it.
    http://learn.jquery.com/code-organization/concepts/

    0 讨论(0)
  • 2021-01-31 06:48

    I've got some experience with Mootools, but I'm a jQuery novice. I've read through the docs, and it looks like the smartest way to organize code is the Module Pattern, so I'm trying that out. However, one thing that seems to be missing from that style is any notion of "self", since each variable within the IIFE is a self-contained object (no pun intended).

    So...maybe this defeats the whole purpose, but could you do something like this, and still have it be "valid" in all the ways that the module pattern style is valid?

    var feature = ( function () {
    
        var self = {
    
            config: {
                option1: 'thing 1',
                option2: 'thing 2'
            },
    
    
            init: function (options) {
    
                // allow overriding the default config
                jQuery.extend( self.config, options );
    
                self.doSomething();
    
            },
    
            doSomething: function () {
    
            },
    
        };
    
        return {
            init: self.init
        }
    
    })();
    

    What I like about this is that I can internally reference all of the methods and properties using "self". I'm still able to expose the methods that I want using the "return" object, so (I guess) that's okay. But I'm such a novice, and this seems so simple and (at first glance) elegant, that I must be missing a major gotcha. It shares the coding style with the Object Literal format, which is what I'm familiar with from Mootools. So maybe I'm trying to fit a round peg into a square hole. Maybe the internal object literal isn't necessary, because rather than "self.doSomething()", I can just say "doSomething"? Is that the case?

    Partially I like this because I can set the "context" argument of $.ajax to be "self", which seems like a win.

    0 讨论(0)
  • 2021-01-31 06:51

    The revealing module pattern is used like this:

    var moduleName = (function () {
        var privateVariable = 'private';
    
        var privateMethod = function () {
            alert('this is private');
        };
    
        // this is the "revealed" part of the module
        return { 
            publicVariable: 'public',
            publicMethod: function () {
                alert('this is public');
            }
        };
    }());
    

    You can also define the public variables/methods as privates and then expose a reference to them, making them public. This is a matter of preference.

    In your example, if you wanted addMessage to be part of the module, you would do it like this:

    var moduleName = (function () {
        // this becomes public due to the reference exposure in the return below
        var addMessage = function () {
            // do whatever
        };
    
        // this is the "revealed" part of the module
        return { 
            addMessage: addMessage
        };
    }());
    
    moduleName.addMessage();
    
    0 讨论(0)
  • 2021-01-31 06:57

    Unlike JAVA, Javascript does not have the concept of private and public on properties or on methods. Let’s create an object called person which has 2 properties firstName and lastName, and also create 2 functions which will be getters for our properties. In Javascript we can create functions as properties of objects & those functions are accessible like any other property anywhere.

    var person={
      "firstName":"Anoop",
      "lastName":"Rai",
      "getFirstName":function(){
        return this.firstName;
      },
      "getLastName":function(){
        return this.lastName;
      }
    };
    console.log(person.getFirstName());
    console.log(person.firstName);
    

    As expected above codes 11 prints Anoop and Anoop. Hmmm, that’s not good for object oriented programming. Well, we successfully implemented getters and so we should also have setters that should be of public scope and properties should be marked as private scope (what??? these private and public concept belongs to JAVA, C++ like languages). Our intentions are good, lets apply concepts specific to Javascript. We don’t want to do person.firstName, we want the prevent the access of the property directly. In languages like JAVA because of private and public we achieved the controlled acccess of properties, but in Javascript everything is public.

    Javascript uses concept of closures to implement things like private & public. This pattern is called Module Pattern. That is, hiding variables from public access. In order to implement scopes, wrap your codes in a function (remember, scopes are implemented via functions in Javascript).

    function createPerson(){
      var returnObj={
        "firstName":"Anoop",
        "lastName":"Rai",
        "getFirstName":function(){
          return this.firstName;
        },
        "getLastName":function(){
          return this.lastName;
        }
      };
      return returnObj;
    }
    var person=createPerson();
    console.log(person.getFirstName());
    console.log(person.firstName);
    

    Now also above lines prints Anoop and Anoop. Still no success. As long as properties are tied to the object it will be accessed directly. Let’s untie it. Instead of properties we make variables of function scope (closure variables).

    function createPerson(){
      var firstName="Anoop";
      var lastName="Rai";
      var returnObj={
        "getFirstName":function(){
          return firstName;
        },
        "getLastName":function(){
          return lastName;
        }
      };
      return returnObj;
    }
    var person=createPerson();
    console.log(person.getFirstName());
    console.log(person.firstName);
    

    Now above lines prints Anoop and undefined. How does this happen? Because of closures, when the functions getFirstName and getLastName was created the functions had the whole scope chain or say pointers to the relevant variables i.e. firstName and lastName. The object returnObj does not remember the variabes but the function objects remembers, because of closures. Looks like we achieved what we wanted to, but one thing is left and that is setters for the controlled access of firstName and lastName. Let’s implement setters.

    function createPerson(){
      var firstName="Anoop";
      var lastName="Rai";
      var returnObj={
        "getFirstName":function(){
          return firstName;
        },
        "getLastName":function(){
          return lastName;
        },
        "setFirstName":function(name){
          return firstName=name;
        },
        "setLastName":function(name){
          return lastName=name;
        }
      };
      return returnObj;
    }
    var person=createPerson();
    console.log(person.getFirstName());
    person.setFirstName("Kumar");
    console.log(person.getFirstName());
    

    We successfully modified firstName but in a controlled manner.

    http://jkoder.com/the-module-pattern-javascript-way-of-hiding-data-in-objects-from-public-access/

    0 讨论(0)
提交回复
热议问题