JS modular development

  1. Advanced singleton design pattern: Create a namespace, receive the information returned from the closure, and expose the contents of the closure so that the contents of the closure are exposed to be invoked by contents outside the closure
    let module1=(function(){
        let n=1;
        function query(){
            return n
        }
        function fn(){
            return n+1
        }
        return {
            query,
            fn
        }
    })()
   let module2=(function(){
       function fn(){
           return true
       }
       // This calls the method in module
       module1.query()
       return {
           fn
       }
   })()
     
Copy the code
     let wetherModule = (function () {
               function query(){
                   return falase
               }
               function func(){
                   return true
               }
               return {
                   init() {
                       / /... Load corresponding methods one by one in service orderquery(); func(); }}}) (); wetherModule.init();Copy the code
  1. AMD modular idea: the earliest modular idea, the definition of the use of define, after the call of the use of require call (understand)
  • Realize sun sum and average average
 / / import
 <script src="./js/require.min.js"></script>
 <script src="./main.js"></script>

 / / moduleA. Js = = = > definition
 define(function() {
     let sum = function sum(. arg) {
         if (arg.length === 0) return 0;
         if (arg.length === 1) return arg[0];
         return arg.reduce((pre, next) = > {
             return pre + next
         }, 0)}return { sum }
 })

 / / moduleB. Js = = = = "definition
 define([
     "js/moduleA.js"].function(moduleA) {
     let average = function average(. arg) {
         debugger
         if (arg.length === 0) return 0;
         if (arg.length === 1) return arg[0];
         return(moduleA.sum(... arg) / arg.length).toFixed(2)}return { average }
 })

 / / the main js = = = "use
 require([
     "js/moduleB.js"].function(moduleB) {
     console.log(moduleB.average)
     let result = moduleB.average(10.20.30.40.50.60.70);
     console.log(result)
 })

Copy the code
  • Their simple implementation of AMD source code
  let factories = {};
  let define = function define(moduleName, dependency, factory) {
    if (typeof dependency === "function") {
      factory = dependency;
    }
    factories[moduleName] = factory;
    if (typeof dependency === "array") {
      let keys = Object.keys(factories);
      dependency = dependency.map((item) = > {
        if (keys.includes(item)) {
          return factories[item]();
        }
        return new Error("You haven't added yet!");
      });
      factory(...dependency);
    }
  };
  let require = function require(dependency, callback) {
    dependency = dependency.map((item) = > {
      returnfactories[item](); }); callback(... dependency); }; define("moduleA".function () {
    return {
      fn() {
        console.log("moduleA"); }}; }); define("moduleB".function () {
    return {
      fn() {
        console.log("moduleB"); }}; });require(["moduleA"."moduleB"].function callback(moduleA, moduleB) {
    moduleA.fn();
    moduleB.fn();
  });
  
Copy the code
  1. CMD modular design idea :node commonly used module import and export methods: require import module,module. Exports module in the method

  2. ES6Module Module concept: new features in ES6: import Import modules,export/export default methods in export modules

CMD and ES6Module differences:

  • CommonJS is run time loaded

  • Es6modules (typically used in conjunction with WebPack in projects) are handled at compile time

Eight advanced singleton design patterns

  1. Advanced singleton design pattern: Create a namespace to manage the contents of a module, and expose the contents of the module, realizing independent partition between modules “but also realizing the method call between modules”
 let SearchModule = (function () {
       let body = document.body;

       function queryData() {}

       function bindHTML() {}

       function handle() {}

       return {
           // Init is a brain that controls who executes first and who executes "command mode" later.
           init: function () {
               queryData();
               bindHTML();
               handle();
           }
       };
   })();
   SearchModule.init();


   let AModule = (function () {
       let arr = [];

       let change = function change(val) {
           arr.push(val);
           console.log(arr);
       };

       return {
           change: change }; }) (); AModule.change(10);
   AModule.change(20);

Copy the code
  1. Constructor Design pattern (common in previous plug-in component packaging)
class AModule {
      constructor() {
        // this-> an instance of each class
        this.arr = [];
      }
      // Common properties and methods on the stereotype
      change(val) {
        this.arr.push(val);
        console.log(this.arr); }}let A1 = new AModule();
 let A2 = new AModule();
 console.log(A1, A2);
 console.log(A1 === A2); //->false
 console.log(A1.arr === A2.arr); //->false
 console.log(A1.change === A2.change); //->true
 A1.change(10);
 A2.change(20);
Copy the code
  1. Factory Mode (JQ Factory mode)
function factory(options) { options = options || {}; let { type, payload } = options; If (type === "array") {// Execute A, complete A logical return; } factory({type: "array", payload: 100,}); factory({ type: "object", payload: "zhufeng", });Copy the code
  1. It has a large potential to be an Observer of the continent.

    • Each observer should have an UPDATE method for notifying messages and processing them when they arrive
    • Objective: Manage observer (add, delete, change, review) and notification message processing capabilities
     //1. Create n observers: there is a method that notifies the message when it arrives
         class observer {
               update(message) {
                     console.log("Message received!", message); }}class demo {
               update(message) {
                     console.log("Message received!", message); }}//2. Create a list of observers, manage the observer (add, delete, change, check and notify the observer method execution)
         class subjecList {
             constructor() {
                 this.observeList = [];
             }
             add(observer) {
                 this.observeList.includes(observer) ?
                         null :
                         this.observeList.push(observer);
                 return this;
             }
             remove(observer) {
                 this.subjecList.filter((item) = >item ! == observer);return this;
             }
             get(index) {
                 return this.observeList[index];
             }
             count() {
                 return this.observeList.length; }}//3. Create a target class that can be used to add, delete, change, query and notify method execution
         class subject {
             observe = new subjecList(); // The subjecList method can be invoked
             add(observe) {
                     this.observe.add(observe);
             }
             remove(observe) {
                     this.observe.remove(observe);
             }
             notify(. args) {
               for (let i = 0; i < this.observe.count(); i++) {
                         let item = this.observe.get(i); item.update(... args); }}}let sub = new subject();
             sub.add(new observer());
             sub.add(new observer());
             sub.add(new demo());
             setTimeout(() = > {
                 sub.notify("Hello ~~ welcome everyone to sign up for Everest training online web advanced!");
             }, 1000);
    Copy the code
  2. Mediator [ˈ ː l ə ː l

    let mediator = (function () {
     let topics = {};
     / / 1. Subscribe to
     let subscribe = function subscribe(topic, callback) { topics[topic] = ! topics[topic] ? [] :null;
       topics[topic].push({
         context: this.callback: callback,
       });
     };
     / / 2. Release
     let publish = function publish(topic, ... args) {
       if(! topics[topic])return;
       topics[topic].foreach((item) = > {
         let{ context, callback } = item; callback.call(context, ... args); }); };return{ subscribe, publish, }; }) ();Copy the code
  1. Publish and subscribe model
(function () {
  const hasOwn = Object.prototype.hasOwnProperty;
  class Sub {
    constructor() {
      //pond={a:[],b:[]}
      this.pond = {};
    }
    $on(type, func) {
      let arr;
      // Check whether pond has events. If not, add events. If yes, add methods directly
      let pond = this.pond; ! hasOwn.call(pond, type) ? (pond[type] = []) :null; arr = pond[type]; ! arr.includes(func) ? arr.push(func) :null;
    }
    $off(type, func) {
      let pond = this.pond,
        arr = pond[type];
      if(! arr)return;
      for (let i = 0; i < arr.length; i++) {
        arr[i] = null; } } $emit(type, ... params) {let pond = this.pond,
        arr = pond[type];
      let func = null;
      if(! arr)return;
      for (let i = 0; i < arr.length; i++) {
        func = arr[i];
        if (typeoffunc ! = ="function") {
          arr.splice(i, 1); i--; } arr[i](... params); }}}// Direct exposure method
  let sub = new Sub();
  ["$on"."$off"."$emit"].forEach((item) = > {
    window[item] = function anonymous(. arg) {
      returnsub[item](... arg); }; }); }) ()Copy the code