IIFE methods leaks?

2020-02-15 16:03发布

问题:

Probably simple question, hope not duplicate even a bit similar like this one, but is there any rule how to write IIFEs properly for any browser, node.js, etc. ?
IIFE examples - second my own created during experiments in IE after watching probably all related Pluralsight videos.
Is there any rule, best practise or specificiation how to write methods properly in IIFEs ?
In 1st (quite common) example leaks everything except constructor
In 2nd not, but not sure why or where to find specifications of this behavior.
There are probably differences between classic functions and their anonymous versions too (event handlers, etc.).
Dog (https://coderwall.com/p/ta4caw/using-iife-to-create-private-members-in-javascript)
true - constructor
false - getter
false - setter both unique in each instance

Chart
true - constructor
true - method has single instance in all objects

var Dog = (function() {
  var name = "defaut name";
  var DogInner = function() {
    this.getName = function() {
      return name;
    };
    this.setName = function(value) {
      name = value;
    };
  };
  return DogInner;
})(); // this does the trick
var results = ["Dog"]
var dog = new Dog();
var dog1 = new Dog();
results.push(dog.Dog === dog1.Dog); // true
results.push(dog.setName === dog1.setName); // false
results.push(dog.setName === dog1.setName); // false

// IIFE object picked from my code
var Chart = (function() {

  function Chart() {}

  Chart.prototype.drawChart = function(data) {}

  return Chart;
})();
results.push(' ');

results.push("Chart");
var chart1 = new Chart();
var chart2 = new Chart();
results.push(chart1.Chart === chart2.Chart); // true
results.push(chart1.drawChart === chart2.drawChart); // true

console.log(results.join('\n'));

回答1:

In case you use this.variable name in your IIFE, it will create instance public variable, but there are only private static or public instance variants possible.



回答2:

Was right also VS Code recognize this "old-school" compatible version as ES2015 class:

'use strict';
 var Utils = (function() {

    function Utils() {}

    function GetUrl(data) {
    }
    Utils.prototype.GetRequest = async function(data) {
        const response = await rp(GetUrl(data));
        return response;
    }

    return Utils;
})();

Converts to similar, less compatible, but more readable:

'use strict';
 var Utils = (function() {

    class Utils {
        constructor() { }
        async GetRequest(data) {
            const response = await rp(GetUrl(data));
            return response;
        }
    }

    function GetUrl(data) {
    }

    return Utils;
})();