Home > OS >  JS advantages of module pattern?
JS advantages of module pattern?

Time:09-13

I know it's a duplicate but I don't understand the other posts: I'm doing an exercise on freeCodeCamp that I don't understand, it's about modules: What's the advantage of doing this:

const motionModule = (function() {
  return {
    isCuteMixin: function(obj) {
      obj.isCute = function() {
        return true;
      };
    },
    singMixin: function(obj) {
      obj.sing = function() {
        console.log("Singing to an awesome tune");
      };
    }
  };
})();

instead of this:

const motionModule = {
  isCuteMixin: function(obj) {
    obj.isCute = function() {
      return true;
    };
  },
  singMixin: function(obj) {
    obj.sing = function() {
      console.log("Singing to an awesome tune");
    };
  }
};

CodePudding user response:

One advantage is you can emulate private variables and methods which are not accessible from outside the returned object. This helps keeping the data and functionality together and avoids corruption of global namespace.

const motionModule = (function() {
  let song = 'My song'; // private variable

  function singTheSong() {
     // private method
  }

  return {
    isCuteMixin: function(obj) {
      obj.isCute = function() {
        return true;
      };
    },
    singMixin: function(obj) {
      obj.sing = function() {
        console.log("Singing to an awesome tune"   song);
        singTheSong();
      };
    }
  };
})();

// cannot call singTheSong from here

CodePudding user response:

Within a module, you would often want the methods to be able to access each other and shared variables. To do this in your 2nd example, you need to attach them to the object and access them via the this keyword, and also (within the mixin creating functions) use arrow functions to ensure this refers to the right object.

const motionModule = {
  song: "La La La",
  sing: function() {
    console.log(this.song);
  },
  singMixin: function(obj) {
    obj.sing = () => {
      console.log(`Singing ${this.song}`);
    };
  }
};
const a = {};
motionModule.sing();
motionModule.singMixin(a);
a.sing();

Modern ES6 class declarations also require you to work in this way.

class MotionModule {
  song = "La La La";
  sing() {
    console.log(this.song);
  }
  singMixin(obj) {
    obj.sing = () => {
      console.log(`Singing ${this.song}`);
    };
  }
}
const motionModule = new MotionModule();
motionModule.sing();
const a = {};
motionModule.singMixin(a);
a.sing();

As shown in another answer, the first example (an immediately invoked function expression) allows you to access other variables and methods defined within the module without using this, and gives you greater control over which methods and variables are accessible from outside the module.

  • Related