Alternatives aux variables de classe ES6

493

Actuellement dans ES5, beaucoup d'entre nous utilisent le modèle suivant dans les frameworks pour créer des classes et des variables de classe, ce qui est confortable:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

Dans ES6, vous pouvez créer des classes en mode natif, mais il n'y a pas d'option pour avoir des variables de classe:

// ES6
class MyClass {
    const MY_CONST = 'string'; // <-- this is not possible in ES6
    constructor(){
        this.MY_CONST;
    }
}

Malheureusement, ce qui précède ne fonctionnera pas, car seules les classes peuvent contenir des méthodes.

Je comprends que je peux this.myVar = trueen constructor… mais je ne veux pas «junk» mon constructeur, surtout quand j'ai 20-30 + params pour une classe plus grande.

Je pensais à de nombreuses façons de gérer ce problème, mais je n'en ai pas encore trouvé de bonnes. (Par exemple: créez un ClassConfiggestionnaire et passez un parameterobjet, qui est déclaré séparément de la classe. Ensuite, le gestionnaire s'attacherait à la classe. Je pensais WeakMapségalement à intégrer, d'une manière ou d'une autre.)

Quel genre d'idées auriez-vous à gérer cette situation?

Wintercounter
la source
1
votre problème principal est que vous aurez une répétition de this.member = memberchez votre constructeur avec 20-30 paramètres?
Θεόφιλος Μουρατίδης
1
Ne pouvez-vous pas simplement utiliser public variable2 = truesous la classe? Cela le définirait sur le prototype.
14
@ Θεόφιλος Μουρατίδης: Oui, et je veux aussi utiliser mon constructeur pour les procédures d'initialisation et non pour les déclarations de variables.
Wintercounter le
@derylius: C'est le principal problème, il n'a pas une telle fonctionnalité. Même l'usage public / privé n'est pas encore décidé dans le projet ES6. Essayez-le: es6fiddle.net
wintercounter
Selon le dernier, il a cette fonction: wiki.ecmascript.org/doku.php?id=harmony:classes

Réponses:

515

Mise à jour 2018:

Il y a maintenant une proposition de phase 3 - je suis impatient de rendre cette réponse obsolète dans quelques mois.

En attendant, toute personne utilisant TypeScript ou babel peut utiliser la syntaxe:

varName = value

A l'intérieur d'un corps de déclaration / expression de classe et il définira une variable. J'espère que dans quelques mois / semaines, je pourrai publier une mise à jour.

Mise à jour: Chrome 74 est désormais livré avec cette syntaxe qui fonctionne.


Les notes dans le wiki ES pour la proposition dans ES6 ( classes maximales minimales ) notent:

Il n'y a (intentionnellement) aucun moyen déclaratif direct de définir les propriétés de classe des propriétés de données du prototype (autres que les méthodes) ou la propriété d'instance

Les propriétés de classe et les propriétés de données de prototype doivent être créées en dehors de la déclaration.

Les propriétés spécifiées dans une définition de classe se voient attribuer les mêmes attributs que si elles apparaissaient dans un littéral d'objet.

Cela signifie que ce que vous demandez a été pris en compte et a été explicitement rejeté.

mais pourquoi?

Bonne question. Les bonnes gens de TC39 veulent que les déclarations de classe déclarent et définissent les capacités d'une classe. Pas ses membres. Une déclaration de classe ES6 définit son contrat pour son utilisateur.

N'oubliez pas qu'une définition de classe définit des méthodes de prototype - la définition de variables sur le prototype n'est généralement pas quelque chose que vous faites. Vous pouvez bien sûr utiliser:

constructor(){
    this.foo = bar
}

Dans le constructeur comme vous l'avez suggéré. Voir également le résumé du consensus .

ES7 et au-delà

Une nouvelle proposition pour ES7 est en cours d'élaboration qui permet des variables d'instance plus concises grâce aux déclarations et expressions de classe - https://esdiscuss.org/topic/es7-property-initializers

Benjamin Gruenbaum
la source
4
@wintercounter la chose importante à en tirer est qu'autoriser la définition de propriétés les définirait sur le prototype comme les méthodes et non sur chaque instance. Les classes maximales minimales sont toujours à leur héritage prototypique de base. Ce que vous voulez vraiment faire dans votre cas, c'est partager la structure et affecter des membres pour chaque instance. Ce n'est tout simplement pas ce que visent les classes dans ES6 - partager des fonctionnalités. Alors oui, pour partager la structure, vous devez vous en tenir à l'ancienne syntaxe. Jusqu'à ES7 au moins :)
Benjamin Gruenbaum
5
Vous voudrez peut-être mentionner des staticpropriétés
Bergi
8
Oups, péter le cerveau. J'ai oublié que cela staticne fonctionne que pour les méthodes.
Bergi
638
Peut-être que les bonnes personnes de TC39 devraient nommer ce concept autre chose que "classe" s'ils ne veulent pas qu'il se comporte comme le reste du monde de la programmation attend de quelque chose nommé "classe".
Alex
7
Voir aussi la proposition "Class Fields & Static Properties" (déjà implémentée dans Babel : github.com/jeffmo/es-class-fields-and-static-properties
Matt Browne
127

Juste pour ajouter à la réponse de Benjamin - les variables de classe sont possibles, mais vous ne les utiliseriez pas prototypepour les définir.

Pour une vraie variable de classe, vous voudriez faire quelque chose comme ceci:

class MyClass {}
MyClass.foo = 'bar';

Depuis une méthode de classe, cette variable est accessible en tant que this.constructor.foo(ou MyClass.foo).

Ces propriétés de classe ne sont généralement pas accessibles depuis l'instance de classe. c'est à dire MyClass.foodonne 'bar'mais new MyClass().fooestundefined

Si vous souhaitez également avoir accès à votre variable de classe à partir d'une instance, vous devrez en outre définir un getter:

class MyClass {
    get foo() {
        return this.constructor.foo;
    }
}

MyClass.foo = 'bar';

Je n'ai testé cela qu'avec Traceur, mais je pense que cela fonctionnera de la même manière dans une implémentation standard.

JavaScript n'a pas vraiment de classes . Même avec ES6, nous examinons un langage basé sur un objet ou un prototype plutôt qu'un langage basé sur une classe. En tout cas function X () {}, X.prototype.constructorrenvoie à X. Lorsque l' newopérateur est utilisé X, un nouvel objet est créé en héritant X.prototype. Toutes les propriétés non définies dans ce nouvel objet (y compris constructor) sont recherchées à partir de là. Nous pouvons penser à cela comme générant des propriétés d'objet et de classe.

lyschoening
la source
29

Babel prend en charge les variables de classe dans ESNext, vérifiez cet exemple :

class Foo {
  bar = 2
  static iha = 'string'
}

const foo = new Foo();
console.log(foo.bar, foo.iha, Foo.bar, Foo.iha);
// 2, undefined, undefined, 'string'
Kosmetika
la source
1
Vous pouvez faire de bar une variable de classe privée en faisant semblant avec "#" comme ceci: #bar = 2;
Lonnie Best
26

Dans votre exemple:

class MyClass {
    const MY_CONST = 'string';
    constructor(){
        this.MY_CONST;
    }
}

Parce que MY_CONST est primitif https://developer.mozilla.org/en-US/docs/Glossary/Primitive nous pouvons simplement faire:

class MyClass {
    static get MY_CONST() {
        return 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

Mais si MY_CONSTest le type de référence comme la static get MY_CONST() {return ['string'];}sortie d'alerte est une chaîne, false . Dans ce cas, l' deleteopérateur peut faire l'affaire:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

Et enfin pour la variable de classe non const:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    static set U_YIN_YANG(value) {
      delete MyClass.MY_CONST;
      MyClass.MY_CONST = value;
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    set MY_CONST(value) {
        this.constructor.MY_CONST = value;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass
// alert: string, true
MyClass.MY_CONST = ['string, 42']
alert(MyClass.MY_CONST);
new MyClass
// alert: string, 42 ; true
Oleg Mazko
la source
5
Veuillez éviter l' deleteopérateur, s'il est seul pour des raisons de performances. Ce que vous voulez vraiment ici, c'est Object.defineProperty.
Bergi
@shinzou Je pensais la même chose. Pas nécessairement la faute du PO, cependant; c'est vraiment le langage qui manque de mécanismes appropriés pour représenter les données d'une manière qui reflète ses relations réelles.
user1974458
17

Étant donné que votre problème est principalement stylistique (ne pas vouloir remplir le constructeur avec un tas de déclarations), il peut également être résolu stylistiquement.

De la façon dont je le vois, de nombreux langages basés sur les classes ont le constructeur être une fonction nommée d'après le nom de classe lui-même. Stylistiquement, nous pourrions utiliser cela pour créer une classe ES6 qui, sur le plan stylistique, a toujours du sens mais ne regroupe pas les actions typiques se déroulant dans le constructeur avec toutes les déclarations de propriétés que nous faisons. Nous utilisons simplement le constructeur JS réel comme "zone de déclaration", puis faisons une classe nommée fonction que nous traitons autrement comme la zone "autres éléments constructeurs", en l'appelant à la fin du vrai constructeur.

"utiliser strict";

classe MyClass
{
    // déclare uniquement vos propriétés, puis appelez this.ClassName (); d'ici
    constructeur(){
        this.prop1 = 'blah 1';
        this.prop2 = 'blah 2';
        this.prop3 = 'blah 3';
        this.MyClass ();
    }

    // toutes sortes d'autres trucs "constructeurs", plus mélangés avec des déclarations
    Ma classe() {
        fais ce que tu veux();
    }
}

Les deux seront appelés lors de la construction de la nouvelle instance.

Sorta comme avoir 2 constructeurs où vous séparez les déclarations et les autres actions de constructeur que vous souhaitez entreprendre, et stylistiquement, il n'est pas trop difficile de comprendre que c'est ce qui se passe aussi.

Je trouve que c'est un style agréable à utiliser pour traiter de nombreuses déclarations et / ou de nombreuses actions devant se produire lors de l'instanciation et souhaitant garder les deux idées distinctes l'une de l'autre.


REMARQUE : Je n'utilise pas à dessein les idées idiomatiques typiques de "l'initialisation" (comme une init()ou une initialize()méthode) car elles sont souvent utilisées différemment. Il y a une sorte de différence présumée entre l'idée de construire et d'initialiser. En travaillant avec des constructeurs, les gens savent qu'ils sont appelés automatiquement dans le cadre de l'instanciation. En voyant une initméthode, beaucoup de gens vont supposer sans un second coup d'œil qu'ils doivent faire quelque chose sous la forme de var mc = MyClass(); mc.init();, car c'est ainsi que vous initialisez généralement. Je n'essaie pas d'ajouter un processus d'initialisation pour l'utilisateur de la classe, j'essaie d'ajouter au processus de construction de la classe elle-même.

Alors que certaines personnes peuvent faire une double prise pendant un moment, c'est en fait le problème: cela leur communique que l'intention fait partie de la construction, même si cela les oblige à faire une double prise et à aller "ce n'est pas comment les constructeurs ES6 fonctionnent "et prennent une seconde en regardant le constructeur réel pour aller" oh, ils l'appellent en bas, je vois ", c'est bien mieux que de NE PAS communiquer cette intention (ou de la communiquer incorrectement) et d'obtenir probablement beaucoup de les gens l'utilisant mal, essayant de l'initialiser de l'extérieur et de la camelote. C'est très intentionnel au schéma que je suggère.


Pour ceux qui ne veulent pas suivre ce modèle, l'exact opposé peut également fonctionner. Fermez les déclarations vers une autre fonction au début. Peut-être le nommer "propriétés" ou "publicProperties" ou quelque chose. Ensuite, mettez le reste des choses dans le constructeur normal.

"utiliser strict";

classe MyClass
{
    Propriétés() {
        this.prop1 = 'blah 1';
        this.prop2 = 'blah 2';
        this.prop3 = 'blah 3';
    }

    constructeur () {
        this.properties ();
        fais ce que tu veux();
    }
}

Notez que cette deuxième méthode peut sembler plus propre, mais elle a également un problème inhérent où elle propertiesest remplacée lorsqu'une classe utilisant cette méthode en étend une autre. Il faudrait donner des noms plus uniques propertiespour éviter cela. Ma première méthode n'a pas ce problème car sa fausse moitié du constructeur porte le nom unique de la classe.

Jimbo Jonny
la source
1
Veuillez ne pas utiliser une méthode prototype nommée d'après la classe elle-même. Ce n'est pas idiomatique dans JS, n'essayez pas de le faire ressembler à une autre langue. Si vous voulez vraiment utiliser cette approche, le nom canonique de la méthode est init.
Bergi
1
@Bergi - initest un motif utilisé souvent, et souvent destiné à être appelé de l'extérieur de la classe lorsque l'utilisateur extérieur veut s'initialiser, c'est-à-dire var b = new Thing(); b.init();. C'est un choix 100% stylistique que je préférerais communiquer, c'est une 2ème fonction qui est automatiquement appelée en profitant des motifs trouvés dans d'autres langues. Il est beaucoup moins probable que quelqu'un regarde cela et suppose qu'il doit appeler la MyClassméthode de l'extérieur, plus probable qu'il réalisera que l'intention est une 2ème méthode agissant dans la construction (c'est-à-dire appelée par elle-même lors de l'instanciation).
Jimbo Jonny
Hm, je pourrais réaliser cela en regardant le constructeur, mais pas à partir du nom de la méthode MyClass.
Bergi
1
@Bergi - Prendre un modèle dans une autre langue et l'appliquer à JS d'une manière qui n'est pas techniquement ce qui se passe, mais qui fonctionne toujours n'est pas complètement sans précédent. Vous ne pouvez pas me dire que personne n'a remarqué que la $myvarfaçon standard de se référer aux variables destinées à contenir des objets jQuery n'est pas similaire au modèle d'avoir $ au début des variables auquel tant de programmeurs PHP sont habitués. Juste cette petite implication que "oui, ce n'est pas exactement la même chose ... mais regardez ... c'est toujours une variable parce que c'est ainsi que les variables sont faites dans certaines langues!" aide.
Jimbo Jonny du
1
Je préfère votre dernière option avec la properties()fonction. Cependant, les choses deviennent un peu plus compliquées lors de l'extension des classes, donc je suggère que si vous utilisez une properties()fonction dans toutes vos classes pour vous déclarer les propriétés de classe que vous préfixez le nom de la méthode avec le nom de la classe (IE: MyClassProperties()afin d'éviter de remplacer accidentellement les appels de fonction dans les sous-classes. N'oubliez pas non plus que tous les appels à super()doivent être déclarés en premier dans le constructeur de la classe.
TheDarkIn1978
14

Et la façon oldschool?

class MyClass {
     constructor(count){ 
          this.countVar = 1 + count;
     }
}
MyClass.prototype.foo = "foo";
MyClass.prototype.countVar = 0;

// ... 

var o1 = new MyClass(2); o2 = new MyClass(3);
o1.foo = "newFoo";

console.log( o1.foo,o2.foo);
console.log( o1.countVar,o2.countVar);

Dans constructeur, vous ne mentionnez que les variables qui doivent être calculées. J'aime l'héritage des prototypes pour cette fonctionnalité - cela peut aider à économiser beaucoup de mémoire (au cas où il y aurait beaucoup de vars jamais assignés).

zarkone
la source
4
Cela n'économise pas la mémoire et rend les performances bien pires que si vous les aviez déclarées dans le constructeur. codereview.stackexchange.com/a/28360/9258
Esailija
2
En outre, cela va à l'encontre du but d'utiliser les classes ES6 en premier lieu. À l'heure actuelle, il ne semble guère possible d'utiliser des classes ES6 comme de vraies classes oop, ce qui est quelque peu décevant ...
Kokodoko
4
@Kokodoko real oop - tu veux dire, comme par exemple en Java? Je suis d'accord, j'ai remarqué que beaucoup de gens sont en colère contre JS parce qu'ils essaient de l'utiliser comme Java, comme ils s'y habituent, parce que la syntaxe JS est similaire, et ils supposent que cela fonctionne de la même manière ... Mais à partir de à l'intérieur, c'est assez différent, on le sait.
zarkone
2
Il ne s'agit pas seulement de la syntaxe du langage. La philosophie OOP se prête assez bien à la programmation en général - en particulier lors de la création d'applications et de jeux. JS a traditionnellement été implémenté dans la création de pages Web, ce qui est assez différent. D'une manière ou d'une autre, ces deux approches doivent se rencontrer, car le Web est de plus en plus axé sur les applications.
Kokodoko
1
@Kokodoko Ce n'est pas parce que c'est une POO différente que ce n'est pas la POO. Les prototypes sont une approche POO 100% valide; personne ne va appeler Self "non-OOP" car il utilise des prototypes. Ne pas correspondre à un autre paradigme de POO signifie simplement cela: c'est différent.
Dave Newton
13

Comme Benjamin l'a dit dans sa réponse, TC39 a explicitement décidé de ne pas inclure cette fonctionnalité au moins pour ES2015. Cependant, le consensus semble être qu'ils l'ajouteront dans ES2016.

La syntaxe n'a pas encore été décidée, mais il existe une proposition préliminaire pour ES2016 qui vous permettra de déclarer des propriétés statiques sur une classe.

Grâce à la magie de babel, vous pouvez l'utiliser aujourd'hui. Activez la transformation des propriétés de classe selon ces instructions et vous êtes prêt à partir. Voici un exemple de syntaxe:

class foo {
  static myProp = 'bar'
  someFunction() {
    console.log(this.myProp)
  }
}

Cette proposition est à un stade très précoce, alors soyez prêt à modifier votre syntaxe au fil du temps.

BonsaiOak
la source
Oui, ce n'est pas ES6. À moins que vous ne sachiez de quoi il s'agit, vous ne devez pas l'utiliser.
Bergi
10

[Long thread, je ne sais pas si c'est déjà répertorié en option ...].
Une alternative simple pour les conants uniquement , serait de définir la const en dehors de la classe. Cela ne sera accessible qu'à partir du module lui-même, sauf s'il est accompagné d'un getter.
Cette façon prototypen'est pas jonchée et vous obtenez le const.

// will be accessible only from the module itself
const MY_CONST = 'string'; 
class MyClass {

    // optional, if external access is desired
    static get MY_CONST(){return MY_CONST;}

    // access example
    static someMethod(){
        console.log(MY_CONST);
    }
}
Hertzel Guinness
la source
Que se passe-t-il si vous a) utilisez a varau lieu de const2) utilisez plusieurs instances de cette classe? Ensuite, les variables externes seront modifiées à chaque instance de la classe
nick carraway
1
fail point @nickcarraway, mon offre ne représente que const, pas comme la question intitulée.
Hertzel Guinness
6

ES7 syntaxe des membres de la classe:

ES7a une solution pour «joncher» votre fonction constructeur. Voici un exemple:

class Car {
  
  wheels = 4;
  weight = 100;

}

const car = new Car();
console.log(car.wheels, car.weight);

L'exemple ci-dessus se présenterait comme suit dans ES6:

class Car {

  constructor() {
    this.wheels = 4;
    this.weight = 100;
  }

}

const car = new Car();
console.log(car.wheels, car.weight);

Soyez conscient lorsque vous utilisez cela que cette syntaxe pourrait ne pas être prise en charge par tous les navigateurs et pourrait devoir être transposée dans une version antérieure de JS.

Bonus: une fabrique d'objets:

function generateCar(wheels, weight) {

  class Car {

    constructor() {}

    wheels = wheels;
    weight = weight;

  }

  return new Car();

}


const car1 = generateCar(4, 50);
const car2 = generateCar(6, 100);

console.log(car1.wheels, car1.weight);
console.log(car2.wheels, car2.weight);

Willem van der Veen
la source
3
Vous avez accompli des variables d'instance, pas des variables de classe.
Tjad Clark
5

Vous pouvez imiter le comportement des classes es6 ... et utiliser vos variables de classe :)

Regarde maman ... pas de cours!

// Helper
const $constructor = Symbol();
const $extends = (parent, child) =>
  Object.assign(Object.create(parent), child);
const $new = (object, ...args) => {
  let instance = Object.create(object);
  instance[$constructor].call(instance, ...args);
  return instance;
}
const $super = (parent, context, ...args) => {
  parent[$constructor].call(context, ...args)
}
// class
var Foo = {
  classVariable: true,

  // constructor
  [$constructor](who){
    this.me = who;
    this.species = 'fufel';
  },

  // methods
  identify(){
    return 'I am ' + this.me;
  }
}

// class extends Foo
var Bar = $extends(Foo, {

  // constructor
  [$constructor](who){
    $super(Foo, this, who);
    this.subtype = 'barashek';
  },

  // methods
  speak(){
    console.log('Hello, ' + this.identify());
  },
  bark(num){
    console.log('Woof');
  }
});

var a1 = $new(Foo, 'a1');
var b1 = $new(Bar, 'b1');
console.log(a1, b1);
console.log('b1.classVariable', b1.classVariable);

Je l'ai mis sur GitHub

Ruslan
la source
0

La façon dont j'ai résolu cela, qui est une autre option (si jQuery est disponible), était de définir les champs dans un objet old-school, puis d'étendre la classe avec cet objet. Je ne voulais pas non plus poivrer le constructeur avec des affectations, cela semblait être une bonne solution.

function MyClassFields(){
    this.createdAt = new Date();
}

MyClassFields.prototype = {
    id : '',
    type : '',
    title : '',
    createdAt : null,
};

class MyClass {
    constructor() {
        $.extend(this,new MyClassFields());
    }
};

- Mise à jour suite au commentaire de Bergi.

Pas de version JQuery:

class SavedSearch  {
    constructor() {
        Object.assign(this,{
            id : '',
            type : '',
            title : '',
            createdAt: new Date(),
        });

    }
}

Vous vous retrouvez toujours avec un constructeur «gras», mais au moins c'est tout dans une classe et assigné en un seul coup.

EDIT # 2: J'ai maintenant bouclé la boucle et j'attribue maintenant des valeurs au constructeur, par exemple

class SavedSearch  {
    constructor() {
        this.id = '';
        this.type = '';
        this.title = '';
        this.createdAt = new Date();
    }
}

Pourquoi? Très simple, en utilisant ce qui précède et quelques commentaires JSdoc, PHPStorm a pu effectuer l'achèvement du code sur les propriétés. Assigner toutes les vars en un seul coup était bien, mais l'impossibilité de coder pour compléter les propriétés, imo, ne vaut pas l'avantage de performance (presque certainement minuscule).

Steve Childs
la source
2
Si vous pouvez faire de la classsyntaxe, vous pouvez aussi le faire Object.assign. Pas besoin de jQuery.
Bergi
Je ne vois aucun intérêt à créer MyClassFieldsun constructeur - il n'a pas de méthode. Pouvez-vous expliquer pourquoi vous avez fait cela (au lieu, disons, d'une simple fonction d'usine qui renvoie un objet littéral)?
Bergi
@Bergi - Probablement une force d'habitude plutôt que toute autre chose, pour être honnête. Aussi un bel appel à propos d'Object.assign - ne savait pas ça!
Steve Childs
0

Eh bien, vous pouvez déclarer des variables à l'intérieur du constructeur.

class Foo {
    constructor() {
        var name = "foo"
        this.method = function() {
            return name
        }
    }
}

var foo = new Foo()

foo.method()
Osama Xäwãñz
la source
1
Vous devrez créer une instance de cette classe pour utiliser cette variable. Les fonctions statiques ne peuvent pas accéder à cette variable
Aditya
0

Vous ne pouvez toujours pas déclarer de classes comme dans un autre langage de programmation. Mais vous pouvez créer autant de variables de classe. Mais le problème est la portée de l'objet de classe. Donc selon moi, la meilleure programmation OOP en Javascript ES6: -

class foo{
   constructor(){
     //decalre your all variables
     this.MY_CONST = 3.14;
     this.x = 5;
     this.y = 7;
     // or call another method to declare more variables outside from constructor.
     // now create method level object reference and public level property
     this.MySelf = this;
     // you can also use var modifier rather than property but that is not working good
     let self = this.MySelf;
     //code ......... 
   }
   set MySelf(v){
      this.mySelf = v;
   }
   get MySelf(v){
      return this.mySelf;
   }
   myMethod(cd){
      // now use as object reference it in any method of class
      let self = this.MySelf;
      // now use self as object reference in code
   }
}
Tyler
la source
-1

Ceci est un combo un peu hack de statique et fonctionne pour moi

class ConstantThingy{
        static get NO_REENTER__INIT() {
            if(ConstantThingy._NO_REENTER__INIT== null){
                ConstantThingy._NO_REENTER__INIT = new ConstantThingy(false,true);
            }
            return ConstantThingy._NO_REENTER__INIT;
        }
}

ailleurs utilisé

var conf = ConstantThingy.NO_REENTER__INIT;
if(conf.init)...
TroyWorks
la source
7
Je recommanderais singleton_instancecomme nom de propriété pour que tout le monde comprenne ce que vous faites ici.
Bergi