web-dev-qa-db-fra.com

Comment s'appelle ce modèle JavaScript et pourquoi est-il utilisé?

J'étudie THREE.js et j'ai remarqué un modèle où les fonctions sont définies comme suit:

var foo = ( function () {
    var bar = new Bar();

    return function ( ) {
        //actual logic using bar from above.
        //return result;
    };
}());

(Exemple voir méthode raycast ici ).

La variation normale d'une telle méthode ressemblerait à ceci:

var foo = function () {
    var bar = new Bar();

    //actual logic.
    //return result;
};

En comparant la première version à la variation normale , la première semble différer en ce que:

  1. Il attribue le résultat d'une fonction auto-exécutable.
  2. Il définit une variable locale au sein de cette fonction.
  3. Il renvoie la fonction réelle contenant une logique qui utilise la variable locale.

La principale différence est donc que dans la première variante, la barre n'est affectée qu'une seule fois, lors de l'initialisation, tandis que la deuxième variante crée cette variable temporaire à chaque appel.

Ma meilleure estimation de la raison pour laquelle cela est utilisé est qu'il limite le nombre d'instances pour la barre (il n'y en aura qu'une) et économise ainsi la surcharge de gestion de la mémoire.

Mes questions:

  1. Cette hypothèse est-elle correcte?
  2. Y a-t-il un nom pour ce modèle?
  3. Pourquoi est-ce utilisé?
100
Patrick Klug

Vos hypothèses sont presque correctes. Examinons-les d'abord.

  1. Il affecte le retour d'une fonction auto-exécutable

Ceci est appelé expression de fonction immédiatement invoquée ou IIFE

  1. Il définit une variable locale au sein de cette fonction

C'est la manière d'avoir des champs d'objet privés en JavaScript car elle ne fournit pas le mot-clé ou la fonctionnalité private autrement.

  1. Il renvoie la fonction réelle contenant la logique qui utilise la variable locale.

Encore une fois, le point principal est que cette variable locale est privée .

Y a-t-il un nom pour ce modèle?

AFAIK vous pouvez appeler ce modèle modèle de module . Citant:

Le modèle de module encapsule la "confidentialité", l'état et l'organisation à l'aide de fermetures. Il fournit un moyen d'envelopper un mélange de méthodes et de variables publiques et privées, en protégeant les pièces contre les fuites dans la portée mondiale et en entrant accidentellement en contact avec l'interface d'un autre développeur. Avec ce modèle, seule une API publique est renvoyée, gardant tout le reste de la fermeture privé.

En comparant ces deux exemples, mes meilleures suppositions sur la raison pour laquelle le premier est utilisé sont:

  1. Il met en œuvre le modèle de conception Singleton.
  2. On peut contrôler la façon dont un objet d'un type spécifique peut être créé en utilisant le premier exemple. Une correspondance étroite avec ce point peut être méthodes d'usine statiques comme décrit dans Java efficace.
  3. C'est efficace si vous avez besoin du même état d'objet à chaque fois.

Mais si vous avez juste besoin de l'objet Vanilla à chaque fois, ce modèle n'ajoutera probablement aucune valeur.

100

Il limite les coûts d'initialisation de l'objet et garantit en outre que toutes les invocations de fonction utilisent le même objet . Cela permet, par exemple, à l'état d'être stocké dans l'objet pour de futures invocations à utiliser.

Bien qu'il soit possible que cela limite l'utilisation de la mémoire, le GC collecte généralement les objets inutilisés de toute façon, donc ce modèle n'est pas susceptible d'aider beaucoup.

Ce modèle est une forme spécifique de fermeture .

11
Fengyang Wang

Je ne sais pas si ce modèle a un nom plus correct, mais cela ressemble à un module pour moi, et la raison pour laquelle il est utilisé est à la fois pour encapsuler et pour maintenir l'état.

La fermeture (identifiée par une fonction dans une fonction) garantit que la fonction interne a accès aux variables de la fonction externe.

Dans l'exemple que vous avez donné, la fonction interne est retournée (et affectée à foo) en exécutant la fonction externe, ce qui signifie que tmpObject continue de vivre dans la fermeture et de multiples appels à la fonction interne foo() fonctionnera sur la même instance de tmpObject.

8
itsmejodie

La principale différence entre votre code et le code Three.js est que dans le code Three.js la variable tmpObject n'est initialisée qu'une seule fois, puis partagée par chaque appel de la fonction retournée.

Cela serait utile pour conserver un état entre les appels, similaire à la façon dont les variables static sont utilisées dans les langages de type C.

tmpObject est une variable privée visible uniquement par la fonction interne.

Il modifie l'utilisation de la mémoire, mais n'est pas conçu pour économiser de la mémoire.

5
mcfedr

Je voudrais contribuer à ce fil intéressant en étendant le concept du modèle de module révélateur, qui garantit que toutes les méthodes et variables restent privées jusqu'à ce qu'elles soient explicitement exposées.

enter image description here

Dans ce dernier cas, la méthode d'addition serait appelée Calculator.add ();

4
carlodurso