web-dev-qa-db-fra.com

Où déclarer les constantes de classe?

J'utilise des membres de la classe pour tenir des constantes. Par exemple.:

function Foo() {
}

Foo.CONSTANT1 = 1;
Foo.CONSTANT2 = 2;

Cela fonctionne très bien, sauf que cela semble un peu désorganisé, avec tout le code spécifique à Foo dans son champ d'application global. J'ai donc pensé à déplacer la déclaration de constante dans la déclaration Foo(), mais le code ne s'exécutera-t-il pas chaque fois que la variable Foo est construite?

Je viens de Java où tout est enfermé dans un corps de classe, donc je pense que JavaScript pourrait avoir quelque chose de similaire à celui-là ou que certains travaux le reproduiraient.

21
Tom Tucker

Tout ce que vous faites dans votre code consiste à ajouter une propriété nommée CONSTANT avec la valeur 1 à l'objet Function nommée Foo, puis à l'écraser immédiatement avec la valeur 2.

Je ne connais pas trop les autres langues, mais je ne crois pas que javascript puisse faire ce que vous semblez tenter.

Aucune des propriétés que vous ajoutez à Foo ne sera exécutée. Ils sont simplement stockés dans cet espace de noms.

Peut-être que vous vouliez créer un prototype d'une propriété sur Foo?

function Foo() {
}

Foo.prototype.CONSTANT1 = 1;
Foo.prototype.CONSTANT2 = 2;

Pas tout à fait ce que vous recherchez.

30
user113716

Vous devez faire vos constantes comme vous l'avez dit:

function Foo() {
}

Foo.CONSTANT1 = 1;
Foo.CONSTANT2 = 2;

Et vous accédez comme ça:

Foo.CONSTANT1;

ou

anInstanceOfFoo.__proto__.constructor.CONSTANT1;

Toutes les autres solutions allouent une autre partie de la mémoire lorsque vous créez un autre objet. Ce n'est donc pas une constante. Vous ne devriez pas faire cela:

Foo.prototype.CONSTANT1 = 1;
14
Soap

SI les constantes doivent être utilisées à l'intérieur de l'objet uniquement:

function Foo() {
    var CONSTANT1 = 1,CONSTANT2 = 2;
}

Sinon, faites comme ça:

function Foo(){
    this.CONSTANT1=1;
    this.CONSTANT2=2;
}

Il est beaucoup plus lisible et plus facile de déterminer le rôle de la fonction.

3
Scott van Looy

Si vous utilisez jQuery, vous pouvez utiliser la fonction $ .extend pour tout classer.

var MyClass = $.extend(function() {
        $.extend(this, {
            parameter: 'param',
            func: function() {
                console.log(this.parameter);
            }
        });
        // some code to do at construction time
    }, {
        CONST: 'const'
    }
);
var a = new MyClass();
var b = new MyClass();
b.parameter = MyClass.CONST;
a.func();       // console: param
b.func();       // console: const
3
Marius Balčytis

Tout d'abord, je vous recommande de déplacer votre déclaration de classe à l'intérieur d'un IIFE . Cela nettoie le code, le rend plus autonome et vous permet d'utiliser des variables locales sans polluer l'espace de noms global. Votre code devient:

var Foo = (function() {
  function Foo() {
  }

  Foo.CONSTANT1 = 1;
  Foo.CONSTANT2 = 2;

  return Foo;
})();

Le problème avec l'affectation directe de constantes à la classe en tant qu'attributs est que celles-ci sont accessibles en écriture. Voir cet extrait:

var output = document.getElementById("output");

var Foo = (function() {
  function Foo() {
  }

  Foo.CONSTANT1 = 1;
  Foo.CONSTANT2 = 2;

  return Foo;
})();

Foo.CONSTANT1 = "I'm not very constant";

output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

La meilleure solution que j'ai trouvée consiste à définir des propriétés en lecture seule pour accéder aux constantes en dehors de la classe.

var output = document.getElementById("output");

var Foo = (function() {
  const CONSTANT1 = "I'm very constant";

  function Foo() {
  }

  Object.defineProperty(Foo, "CONSTANT1", {
    get: function() {
      return CONSTANT1;
    },
  });

  return Foo;
})();

Foo.CONSTANT1 = "some other value";

output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

(Techniquement, vous pouvez abandonner l'instruction const CONSTANT1 et simplement renvoyer la valeur de la définition de la propriété, mais je préfère cela, car cela facilite la visualisation de toutes les constantes d'un coup d'œil.)

2
Scott Weldon

ce que vous faites est bien (en supposant que vous réalisiez que votre exemple consiste simplement à définir deux fois la même propriété); c'est l'équivalent d'une variable statique en Java (aussi proche que possible, du moins sans beaucoup de travail). En outre, ce n'est pas tout à fait global, puisque c'est sur la fonction constructeur, il est effectivement attribué à votre 'classe'.

2
hvgotcodes

Aussi avec des espaces de noms

var Constants = {
    Const1: function () {
        Const1.prototype.CONSTANT1 = 1;
        Const1.prototype.CONSTANT2 = 2;
    },

    Const2: function () {
        Const2.prototype.CONSTANT3 = 4;
        Const2.prototype.CONSTANT4 = 3;
    }
};
1
Amc_rtty

Vos constantes ne sont que des variables et vous ne saurez pas si vous essayez de les écraser par inadvertance. Notez également que Javascript ne possède pas la notion de "classe".

Je vous suggère de créer des fonctions qui renvoient des valeurs dont vous avez besoin. 

Pour avoir le goût de Javascript, trouvez Javascript: les bonnes parties et découvrez les méthodes idiomatiques. Javascript est very différent de Java.

1
9000

Vous avez dit venir de Java. Pourquoi ne pas stocker cette classe dans un fichier puis dans des constantes à la fin du fichier. C'est ce que j'utilise:

nom de fichier: PopupWindow.js

function PopupWindow() {
    //private class memebers
    var popup, lightbox;
    //public class memeber or method (it is the same in JS if I am right)
    this.myfuncOrmyMemeber = function() {};
}

//static variable
PopupWindow._instance = null;
//same thing again with constant-like name (you can't have "final" in JS if I am right, so it is not immutable constant but its close enough ;) - just remember not to set varibales with BIG_LETTERS :D)
PopupWindow.MY_CONSTANT = 1;
//yea, and same thing with static methods again
PopupWindow._getInstance = function() {};

La seule différence est donc la position des objets statiques. Il n’est pas bien aligné à l’intérieur des accolades de classe, mais cela ne fait rien, ctrl + clic toujours dans IDE (ou j’utilise ctr + l pour afficher toutes les méthodes de classe - IntellijIdea peut le faire dans JS dunno. IDEs) donc tu ne vas pas le chercher par tes yeux;)

Oui et j'utilise _ avant la méthode statique - ce n'est pas nécessaire, je ne sais pas pourquoi j'ai commencé à le faire :)

0
Srneczek