789 votes

Variables statiques en JavaScript

Comment créer des variables statiques en Javascript ?

0 votes

Nous pouvons définir une étiquette ou une autre balise html avec l'attribut de style "dispaly:none" et définir une valeur variable pour cette valeur et effectuer des opérations sur cette valeur. Ne prenons pas de risques.

0 votes

La solution la plus simple que j'ai trouvée est de ne pas définir de variable statique dans la classe. Lorsque vous voulez utiliser une variable statique, définissez-la simplement à ce moment-là, par exemple someFunc = () => { MyClass.myStaticVariable = 1; } . Il suffit ensuite de créer une méthode statique pour renvoyer le membre statique, par exemple static getStatic() { return MyClass.myStaticVariable; } . Il vous suffit alors d'appeler MyClass.getStatic() de l'extérieur de la classe pour s'emparer des données statiques !

0 votes

VOIR LA MISE À JOUR 2021 POUR SAVOIR COMMENT UTILISER LES CHAMPS STATIQUES. ET LES MEMBRES DE CLASSE STATIQUES À PARTIR DE 4/2021. BEAUCOUP DE CHOSES ONT CHANGÉ !

936voto

CMS Points 315406

Si vous venez d'un langage orienté objet basé sur les classes et à typage statique (comme Java, C++ ou C#) Je suppose que vous essayez de créer une variable ou une méthode associée à un "type" mais pas à une instance.

Un exemple utilisant une approche "classique", avec des fonctions de construction, pourrait peut-être vous aider à comprendre les concepts de base de l'OO JavaScript :

function MyClass () { // constructor function
  var privateVariable = "foo";  // Private variable 

  this.publicVariable = "bar";  // Public variable 

  this.privilegedMethod = function () {  // Public Method
    alert(privateVariable);
  };
}

// Instance method will be available to all instances but only load once in memory 
MyClass.prototype.publicMethod = function () {    
  alert(this.publicVariable);
};

// Static variable shared by all instances
MyClass.staticProperty = "baz";

var myInstance = new MyClass();

staticProperty est défini dans l'objet MyClass (qui est une fonction) et n'a rien à voir avec ses instances créées, JavaScript traite les fonctions comme des objets de première classe En tant qu'objet, vous pouvez donc attribuer des propriétés à une fonction.

UPDATE : ES6 a introduit la possibilité de déclarer des classes par le biais de la class mot-clé. Il s'agit d'un sucre syntaxique par rapport à l'héritage existant basé sur les prototypes.

En static mot-clé vous permet de définir facilement des propriétés ou des méthodes statiques dans une classe.

Voyons l'exemple ci-dessus mis en œuvre avec des classes ES6 :

class MyClass {
  // class constructor, equivalent to
  // the function body of a constructor
  constructor() {
    const privateVariable = 'private value'; // Private variable at the constructor scope
    this.publicVariable = 'public value'; // Public property

    this.privilegedMethod = function() {
      // Public Method with access to the constructor scope variables
      console.log(privateVariable);
    };
  }

  // Prototype methods:
  publicMethod() {
    console.log(this.publicVariable);
  }

  // Static properties shared by all instances
  static staticProperty = 'static value';

  static staticMethod() {
    console.log(this.staticProperty);
  }
}

// We can add properties to the class prototype
MyClass.prototype.additionalMethod = function() {
  console.log(this.publicVariable);
};

var myInstance = new MyClass();
myInstance.publicMethod();       // "public value"
myInstance.additionalMethod(); // "public value"
myInstance.privilegedMethod(); // "private value"
MyClass.staticMethod();             // "static value"

6 votes

Vraisemblablement privilegedMethod n'est pas équivalent à une méthode privée en OO parce qu'il semble qu'il pourrait être appelé sur une instance de MyClass ? Voulez-vous dire qu'elle est privilégiée parce qu'elle peut accéder à privateVariable ?

0 votes

Oui, c'est l'idée de privilégié comme prévu lors de l'explication initiale dans le présent document. Article Crockford

0 votes

Global et Static sont-ils identiques ? Par conséquent, la référence est toujours statique lors de la déclaration d'une variable ou d'une fonction en Javascript ?

567voto

Pascal MARTIN Points 195780

Vous pouvez tirer parti du fait que les fonctions JS sont également des objets, ce qui signifie qu'elles peuvent avoir des propriétés.

Par exemple, en citant l'exemple donné dans l'article (aujourd'hui disparu) Variables statiques en Javascript :

function countMyself() {
    // Check to see if the counter has been initialized
    if ( typeof countMyself.counter == 'undefined' ) {
        // It has not... perform the initialization
        countMyself.counter = 0;
    }

    // Do something stupid to indicate the value
    alert(++countMyself.counter);
}

Si vous appelez cette fonction plusieurs fois, vous verrez que le compteur est incrémenté.

Et c'est probablement une bien meilleure solution que de polluer l'espace de noms global avec une variable globale.

Voici une autre solution possible, basée sur une fermeture : Astuce pour utiliser des variables statiques en javascript :

var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.

Ce qui donne le même type de résultat - sauf que, cette fois, la valeur incrémentée est renvoyée, au lieu d'être affichée.

58 votes

En guise de raccourci, vous pouvez simplement faire countMyself.counter = countMyself.counter || initial_value; si la variable statique ne sera jamais fausse (false, 0, null, ou chaîne vide)

3 votes

Légèrement plus court et plus clair : (function() { var id = 0 ; function uniqueID() { return id++ ; } ; })() ;

3 votes

Le compteur dans la fermeture est très rapide que dans la classe dans Firefox. jsperf.com/static-counter-in-class-vs-in-closure

111voto

khoomeister Points 974

Vous le faites par le biais d'une IIFE (expression de fonction invoquée immédiatement) :

var incr = (function () {
    var i = 1;

    return function () {
        return i++;
    }
})();

incr(); // returns 1
incr(); // returns 2

24 votes

Je dirais que c'est la façon la plus idiomatique de le faire en JavaScript. Dommage qu'elle n'obtienne pas beaucoup de votes positifs grâce à d'autres méthodes qui sont probablement plus agréables pour les gens qui viennent d'autres langages.

1 votes

Je reformulerais en utilisant "closure" plutôt que "IIFE".

0 votes

Félicitations, sans aucun doute la meilleure réponse, la simplicité est belle. Même si c'est évident, je me permets de prolonger la réponse : var incr = (function (delta) { var i = 1; return function (delta) return i+=delta;} })();

39voto

gpilotino Points 5644

Vous pouvez utiliser arguments.callee pour stocker des variables "statiques" (c'est également utile dans les fonctions anonymes) :

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}

3 votes

D'après ce que j'ai compris, cette méthode a un (seul ?) avantage sur celle de pascal MARTIN : on peut l'utiliser sur des fonctions anonymes. Un exemple de ceci serait génial

29 votes

arguments.callee est obsolète.

0 votes

Je ridiculise presque tout le temps les JS, mais callee semble être une bonne chose à avoir. Je me demande pourquoi ils ont décidé de le déprécier... :| |

29voto

jim_zike_huang Points 131
function Person(){
  if(Person.count == undefined){
    Person.count = 1;
  }
  else{
    Person.count ++;
  }
  console.log(Person.count);
}

var p1 = new Person();
var p2 = new Person();
var p3 = new Person();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X