3
votes

Comment s'appelle-t-elle lorsqu'une fonction se comporte comme une classe mais n'utilise pas le mot-clé class, ni le mot-clé "new" (en Javascript)?

J'ai parcouru les liens suggérés , mais je n'arrive pas à trouver le terme pour un fonction qui agit comme une classe (est-ce une fonction de constructeur? n'a pas non plus ce mot-clé!) mais n'utilise pas le mot-clé new , ni class .

J'ai utilisé à la fois le modèle de cet exemple et le modèle de classe dans mon code, mais j'ai réalisé que je ne sais pas comment décrire le premier.

Je pense que c'est en partie parce que j'ai appris JS récemment, j'ai vu beaucoup de class jeté un peu partout, tout en regardant mes notes de pas -ES5 , 6,7,2018,2020 etc. ne semblent pas trouver ce que var aCounter = counterFunction () est appelé pour la vie de moi.

Je sais ce que le résultat de ce que je fais, c'est comment le faire fonctionner, etc. mais pourquoi pas de constructor () , pas de nouveau , pas de classe , non etc.prototype.etc modèle? Je sais que je crée un objet, j'appelle une méthode existante dans l'objet, etc. Je crois que je commence à me balader.

Lo, un exemple

aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2 


0 commentaires

4 Réponses :


3
votes

C'est juste une fonction qui renvoie un objet littéral, qui n'agit pas comme une classe (n'a pas de prototype, et comme vous l'avez souligné, n'utilise pas new , etc.).

Les fonctions définies comme propriétés de cet objet (que vous stockez dans aCounter ) semblent agir comme des méthodes de classe car elles conservent la référence à la variable val vivant, mais ce n'est pas parce que val est en aucune façon associé à l'objet réel.

Au lieu de cela, ces fonctions sont closures qui gardent la référence à la variable active aussi longtemps que les fonctions elles-mêmes sont actives.

Donc pour répondre à votre question, ce que vous avez décrit n'a pas de nom en particulier. C'est juste une fonction qui renvoie un objet.

Edit:

Vous avez demandé pourquoi il n'y a pas de constructor () ou associé syntaxe dans ce modèle. Les littéraux d'objet en JavaScript ne sont que des mappages de noms et de valeurs:

class A
{
    constructor() 
    {
        this.a = new Date();
        this.b = this.a.toString(); // you cannot do this in an object literal
    }
}

const x = new A();

Vous n'avez pas besoin d'un constructeur pour cela, et il n'y a pas de prototype car il n'a pas été instancié à l'aide d'un constructeur. D'autre part, les classes et les fonctions constructeur sont des modèles d'objets qui seront créés ultérieurement, et ces objets ont un prototype et un constructeur car le modèle contient une logique qui s'initialise l'objet.

const x = { a: 3, b: "hello" };


0 commentaires

1
votes

Ce que vous avez montré n'a rien de spécial. C'est juste une fonction normale qui a une fermeture.

Cependant, vous pouvez l'appeler comme un type de modèle de conception .

Il ressemble au modèle de module de révélation où vous pouvez séparer la propriété publique et la propriété privée.

Voici un exemple (pas un bon tho):

var counter = function(){

  var privateCount = 0;
  var privateHistory = [];
  
  return {
    getVal: function(){
      return privateCount;
    },
    increment: function(){
      privateCount++;
      privateHistory.push('+');
      return this.getVal();
    },
    decrement: function(){
      privateCount--;
      privateHistory.push('-');
      return this.getVal();
    },
    publicHistory: function(){
      return privateHistory;
    }
  }
}

var aCounter = counter();
console.log(aCounter.increment());
console.log(aCounter.decrement());
console.log(aCounter.publicHistory());

Ici, vous ne pouvez pas manipuler directement les variables privées que je ne vous expose pas.

Vous ne pouvez manipuler ces variables privées que si je vous expose la fonction. Dans ce cas, les fonctions .increment () et .decrement () .

Comme vous pouvez le voir, il n'y a pas de classe , pas de prototype , pas de constructeur .

p>


0 commentaires

1
votes

Je peux voir comment vous pourriez vous faire trébucher, passons en revue votre code et explorons ce qui se passe:

and works like

aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2 

À ce stade, counterFunction est une variable qui pointe vers une fonction, c'est essentiellement un nom de fonction. () => {...} est le corps de la fonction ou la définition de la fonction et à l'intérieur, l'instruction return montre qu'elle renvoie un objet sans nom avec deux méthodes de propriété.


let aCounter = counterFunction() // where i'm getting tripped up

Ceci appelle votre fonction précédemment définie, qui retourne à nouveau l'objet avec deux méthodes et l'assigne à la variable aCounter . Si vous répétiez la même chose pour une variable appelée bCounter , ils contiendraient deux objets indépendants.


const counterFunction = () => {
    let val = 0

    return { 
      increment() { val++ }, 
      getVal() { return val }
    }
}

Parce que la méthode à l'intérieur de l'objet fait référence à une variable en dehors de la portée de l'objet, mais dans le corps de la fonction, une fermeture est créée afin que l'état de val puisse être conservé. Comme la variable est en cours d'utilisation, le processus de nettoyage du navigateur l'ignore, donc la fonction est toujours conservée en mémoire, je crois jusqu'à ce que l'objet soit détruit et que la variable de la fonction ne soit plus utilisée.


0 commentaires

1
votes

< gagnantQuestion :

Comment s'appelle-t-elle lorsqu'une fonction se comporte comme une classe mais n'utilise pas le mot-clé class, ni le mot-clé «nouveau» (en Javascript)?

< gagnantRéponse :

C'est ce qu'on appelle une "fonction d'usine".

Les fonctions de fabrique renvoient généralement un objet d'un type cohérent mais ne sont pas des instances de la fonction de fabrique elle-même. Les objets renvoyés hériteraient rarement de la propriété prototype de la fonction de fabrique, et l'appel de la fonction de fabrique ne nécessite pas de new avant que la fonction ne soit appelée.


0 commentaires