Inkapseling in JavaScript

Lang geleden zag ik iemand hun hele JavaScript-blok inkapselen met code zoals de onderstaande code:

(function() {
  // ...
})(this);

Vragen:

  1. Is de bovenstaande code correct?
  2. Welk voordeel heeft het om het hele JavaScript-blok in te kapselen zoals hierboven aangegeven?

Antwoord 1, autoriteit 100%

Ja, dat klopt. Het wordt een zelfoproepende anonieme functie-expressie genoemd.

JavaScript-variabelen hebben een functiebereik of een globaal bereik. Er is geen blokomvang. Door uw code in te sluiten in een functie die zichzelf aanroept, zoals die in uw voorbeeld, wordt een tijdelijk lokaal bereik gecreëerd voor eenmalig gebruik, onmiddellijk uitgevoerde code, zonder de globale naamruimte te vervuilen.

Denk aan het volgende:

<html>
<body>
...
<script>
   (function() { 
      var x = '';
      function myFunction () {
         alert('Hello: ' + x);
      }
      x = 'Bob';
      myFunction();
      alert(typeof x);            // string
      alert(typeof myFunction);   // function
   })();
   alert(typeof x);               // undefined
   alert(typeof myFunction);      // undefined
</script>
<script src="other-javascript.js"></script>
</body>
</html>

Alles wat u in die zelfaanroepende functie declareert, wordt in een afzonderlijk bereik gehouden. De variabele xen de functie myFunction()zijn nergens anders toegankelijk. De code in other-javascript.jszal ze bijvoorbeeld niet zien, en het zou vrij zijn om een ​​andere functie myFunction()zonder conflicten te declareren.


Antwoord 2, autoriteit 43%

Als aanvulling op het antwoord van @Daniel, is het doorgeven van thisaan de functie een gebruikelijk patroon om een ​​verwijzing naar het globale object te hebben, bijvoorbeeld:

(function(window){
})(this);

Bij browserscripting heeft het globale object een eigenschap met de naam windowdie verwijst naar het globale object zelf, in andere omgevingen is er geen eigenschap window.

Een ander ding dat gedaan kan worden is om een ​​argument met de naam undefinedop te geven, omdat de eigenschap undefinedniet wordt beschreven op de ECMAScript 3rd. Edition Standard (er is geen garantie dat deze bestaat of niet), en in sommige implementaties is de eigenschap veranderlijk, bijvoorbeeld:

(function(window, undefined){
})(this);

In het bovenstaande voorbeeld hebben we twee lokale identifiers(die iets sneller op te lossen zijn), windowen undefined, alleen de de eerste wordt doorgegeven (this, die altijd verwijst naar het globale object in Globale code(code die buiten elke functie valt)), en de tweede zal de primitieve undefinedwaarde, omdat we er geen waarde aan doorgeven.

Dat patroon wordt gebruikt door sommige bibliotheken zoals jQuery.


Antwoord 3

Voor alle duidelijkheid: ECMA TC39 had een privésyntaxis voorgesteld. Volgens het voorstel, om een ​​javascript class-veld privé te maken, moet je het voorafgaan met een hash ‘#’. Dit is om een ​​soort runtime-inkapseling te bieden.

Voorbeeld:

class B {
  #hidden = 0;
  m() {
    return this.#hidden;
  }
}

Chrome ondersteunt dit sinds Chrome v74. Als deze privé-syntaxis een standaard wordt, kunnen we profiteren van runtime-inkapseling in javascript en vermoedelijk in typoscript, aangezien de transpilatie op die manier wordt bijgewerkt.

Other episodes