Front-end multi-person collaboration-global variable contamination problem (anonymous IIFE/ES6 block-level scope)

Keywords: JQuery Windows

Preface

In large-scale front-end project development, every developer can define and save all the global variables of application resources. If too many global variables are defined, it is likely to cause conflicts among global variables, that is, the pollution problem of global variables. Too many global variables will not only cause naming conflicts, but also weaken the flexibility of the program and increase the coupling between modules. In the future, it will be very difficult to merge and join modules.

As shown in the figure above, there is only one global object. When each module is coupled, programmer A and programmer C conflict, programmer B and programmer C conflict again. It can be seen that global variable pollution will be a nightmare of a large project. Modification and debugging among modules will greatly affect the efficiency of development, and obviously it is not intelligent. Ming. In order to avoid too many such conflicts and lower coupling between modules, such pollution must be reduced or isolated.

I think in small front-end projects, in order to increase development efficiency, it is absolutely possible to ignore the problem of global variable pollution.

Contaminated JQuery global variable (JQuery/$)

// __ Assuming that JQuery and required DOM elements have been introduced___
// Attempt to visit$
console.log(window.$) //ƒ(e,t){return new w.fn.init(e,t)}
// Trying to pollute$
var $ = `contaminated[Pollution success]`
console.log(window.$) //contaminated [pollution success]
// Try to use$
$('#demo').click(function (){
  window.alert(`Pollution failed!`)//$ is not a function
})

When I first visited window. $, everything was calm. When I named it and reassigned it to the window, I could see that the print result had become the string "contaminated [contaminated successfully]" I defined. Finally, when I selected DOM nodes with the $normally provided by JQuery, "$is not a function" did not occur. There are errors.

JQuery code, which is normally running, is "paralyzed" by a global variable pollution, which shows how terrible global variable pollution is.

Anonymous IIFE

Variables and functions directly defined in the document (not nested under any domain) are global, that is, they are all under the top-level object window of the current page. According to the question in the preface, can we use anonymous IIFE to isolate every programmer's global variables? How to isolate? Will it affect anything?

If each programmer defines an object to store its own variables through attributes, then mounts the object into window s, and finally accesses its attributes and methods through. This not only isolates variable pollution, but also achieves the purpose of sharing, as shown in the figure:

As shown in the figure above, turn your thinking into code:

// Anonymous IIFE (isolation and sharing)
(function(obj){  
  // Here, just like ES6 block-level scopes / defined local variables do not interfere with and mutually exclusive with external variables (++ isolation ++)
  // It is also allowed to pass parameters in / such as Package_A / when the last call is made / such as window (++ shared ++).

  // Define each developer's "proprietary" object package
  var Package_A = {};//Define an A package   
  
  // Mount values and methods to the object package
  Package_A.msg = `msg`;
  Package_A.Show = function (){
    console.log(`Show Method`)
  };
  
  // Mount Object Package_A under Windows
  obj.Package_A = Package_A;
      
})(window);

// Attempt to access custom package Package_A
console.log(window.Package_A)//{msg: "msg", Show: ƒ}

// Attempt to pollute msg
var msg = new Error()
console.log(window.msg)//Error
console.log(window.Package_A.msg)//msg

// Attempt to access custom package Package_A attributes and methods (shared successfully)
console.log(window.Package_A.Show())//Show method
console.log(window.Package_A.msg)//msg

In this way, programmer A customizes an object package through anonymous IIFE, and loads all variables and methods into the object package. However, programmer B/programmer C also has its own object package. As long as each developer's object package name does not conflict, there will be no global variable pollution problem.

ES6 Block Scope

The purpose of anonymous IIFE is to create a block-level scope, so that some variables out of this scope are destroyed immediately, so that the variables are not polluted. Now with the concept of ES6 block-level scope, using anonymous IIFE is no longer the only choice, because ES6 block-level scope can solve the global variable pollution problem more concisely.

To quote Professor Ruan Yifeng, the emergence of block-level scopes has virtually eliminated the need for widely used anonymous immediate execution of functional expressions (anonymous IIFE).

Instead of using anonymous IIFE to simulate the concept of block-level scopes, use real block-level scopes:

// [Block-level scope]
// Define each developer's "proprietary" object package
let Package_A = {

  // Mount values and methods to the object package
  msg: `msg`,
  Show: function (){
    console.log(`Show Method`)
  }
}

// Attempt to access custom package Package_A
console.log(Package_A)//{msg: "msg", Show: ƒ}

// Check whether Package_A is mounted in window
console.log(window.Package_A)//undefined

// Attempt to pollute msg
let msg = new Error()
console.log(msg)//Error
console.log(Package_A.msg)//msg

// Attempt to access custom package Package_A attributes and methods (shared successfully)
console.log(Package_A.Show())//Show method
console.log(Package_A.msg)//msg

Similarly, using the concept of block-level scope, each developer maintains its own independent region, which is better than anonymous IIFE. This is natural, because anonymous IIFE is designed to simulate block-level scopes. We should actively use the concept of block-level scopes instead of anonymous IIFE to simulate block-level scopes.

{
...end
}

Posted by justdiy on Wed, 11 Sep 2019 02:06:35 -0700