Variabili statiche in JavaScript

Come posso creare variabili statiche in Javascript?

Se provieni da un linguaggio orientato agli oggetti basato su classi, tipicamente orientato agli oggetti (come Java, C ++ o C #) presumo che tu stia cercando di creare una variabile o un metodo associato a un “tipo” ma non a un’istanza.

Un esempio che utilizza un approccio “classico”, con le funzioni di costruzione potrebbe forse aiutarti a cogliere i concetti di JavaScript OO di base:

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 è definita nell’object MyClass (che è una funzione) e non ha nulla a che fare con le sue istanze create, JavaScript considera le funzioni come oggetti di prima class , quindi essendo un object, è ansible assegnare proprietà a una funzione.

Potresti approfittare del fatto che le funzioni JS sono anche oggetti – il che significa che possono avere proprietà.

Per esempio, citando l’esempio dato sull’articolo (ora scomparso) Variabili statiche in 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); } 

Se chiami quella funzione più volte, vedrai che il contatore sta per essere incrementato.

E questa è probabilmente una soluzione molto migliore rispetto all’immissione in commercio del namespace globale con una variabile globale.

Ed ecco un’altra ansible soluzione, basata su una chiusura: Trucco per usare variabili statiche in 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. 

Il che ti dà lo stesso tipo di risultato – tranne, questa volta, il valore incrementato viene restituito, anziché visualizzato.

Lo fai attraverso un IIFE (espressione di funzione immediatamente invocata):

 var incr = (function () { var i = 1; return function () { return i++; } })(); incr(); // returns 1 incr(); // returns 2 

puoi usare arguments.callee per memorizzare le variabili “statiche” (questo è utile anche nella funzione anonima):

 function () { arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1; arguments.callee.myStaticVar++; alert(arguments.callee.myStaticVar); } 
 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(); 

Ho visto un paio di risposte simili, ma vorrei menzionare che questo post lo descrive meglio, quindi mi piacerebbe condividerlo con te.

Ecco un codice preso da esso, che ho modificato per ottenere un esempio completo che, se tutto va bene, dà beneficio alla comunità perché può essere usato come modello di design per le classi.

Risponde anche alla tua domanda:

 function Podcast() { // private variables var _somePrivateVariable = 123; // object properties (read/write) this.title = 'Astronomy Cast'; this.description = 'A fact-based journey through the galaxy.'; this.link = 'http://www.astronomycast.com'; // for read access to _somePrivateVariable via immutableProp this.immutableProp = function() { return _somePrivateVariable; } // object function this.toString = function() { return 'Title: ' + this.title; } }; // static property Podcast.FILE_EXTENSION = 'mp3'; // static function Podcast.download = function(podcast) { console.log('Downloading ' + podcast + ' ...'); }; 

Dato questo esempio, puoi accedere alle proprietà / funzioni statiche come segue:

 // access static properties/functions Podcast.FILE_EXTENSION; // 'mp3' Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...' 

E le proprietà dell’object / funzioni semplicemente come:

 // access object properties/functions var podcast = new Podcast(); podcast.title = 'The Simpsons'; console.log(podcast.toString()); // Title: The Simpsons console.log(podcast.immutableProp()); // 123 

Si noti che in podcast.immutableProp (), abbiamo una chiusura : il riferimento a _somePrivateVariable viene mantenuto all’interno della funzione.

Puoi persino definire getter e setter . Dai un’occhiata a questo snippet di codice (dove d è il prototipo dell’object per il quale vuoi dichiarare una proprietà, y è una variabile privata non visibile all’esterno del costruttore):

 // getters and setters var d = Date.prototype; Object.defineProperty(d, "year", { get: function() {return this.getFullYear() }, set: function(y) { this.setFullYear(y) } }); 

Definisce la proprietà d.year con funzioni get e set – se non si specifica set , la proprietà è di sola lettura e non può essere modificata (attenzione che non si verificherà un errore se si tenta di impostarlo, ma non ha alcun effetto). Ogni proprietà ha gli attributi writable , configurable (consente di modificare dopo la dichiarazione) ed enumerable (consente di utilizzarli come enumeratore), che per impostazione predefinita sono false . È ansible impostarli tramite defineProperty nel terzo parametro, ad esempio enumerable: true .

Ciò che è anche valido è questa syntax:

 // getters and setters - alternative syntax var obj = { a: 7, get b() {return this.a + 1;}, set c(x) {this.a = x / 2} }; 

che definisce una proprietà leggibile / scrivibile a , una proprietà readonly b e una proprietà write-only c , attraverso cui è ansible accedere alla proprietà a.

Uso:

 console.log(obj.a); console.log(obj.b); // output: 7, 8 obj.c=40; console.log(obj.a); console.log(obj.b); // output: 20, 21 

Gli appunti:

Per evitare comportamenti imprevisti nel caso in cui hai dimenticato la new parola chiave, ti suggerisco di aggiungere quanto segue alla funzione Podcast :

 // instantiation helper function Podcast() { if(false === (this instanceof Podcast)) { return new Podcast(); } // [... same as above ...] }; 

Ora, entrambe le seguenti istanze funzioneranno come previsto:

 var podcast = new Podcast(); // normal usage, still allowed var podcast = Podcast(); // you can omit the new keyword because of the helper 

La ‘nuova’ istruzione crea un nuovo object e copia tutte le proprietà e i metodi, es

 var a=new Podcast(); var b=new Podcast(); a.title="a"; b.title="An "+b.title; console.log(a.title); // "a" console.log(b.title); // "An Astronomy Cast" 

Si noti inoltre che in alcune situazioni può essere utile utilizzare l’istruzione return nella funzione di costruzione Podcast per restituire a un object personalizzato funzioni di protezione di cui la class si basa internamente ma che devono essere esposte. Questo è ulteriormente spiegato nel capitolo 2 (Oggetti) della serie di articoli.

Puoi dire che a e b ereditano dal Podcast . Ora, cosa succede se si desidera aggiungere un metodo a Podcast che si applica a tutti dopo che b è stato instanciato? In questo caso, utilizzare .prototype come segue:

 Podcast.prototype.titleAndLink = function() { return this.title + " [" + this.link + "]"; }; 

Adesso chiama a e b nuovo:

 console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]" console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]" 

Puoi trovare maggiori dettagli sui prototipi qui . Se vuoi fare più eredità, ti suggerisco di esaminare questo .


Le serie di articoli che ho menzionato sopra sono altamente raccomandate per la lettura, includono anche i seguenti argomenti:

  1. funzioni
  2. Oggetti
  3. prototipi
  4. Applicare nuove funzioni di costruzione
  5. sollevamento
  6. Inserimento automatico di punti e virgola
  7. Proprietà e metodi statici

Si noti che la “funzione” di inserimento automatico del punto e virgola di JavaScript (come menzionato in 6.) è molto spesso responsabile di causare strani problemi nel codice. Quindi, preferirei considerarlo un bug piuttosto che una funzionalità.

Se vuoi saperne di più, ecco un articolo MSDN piuttosto interessante su questi argomenti, alcuni dei quali descritti forniscono ulteriori dettagli.

Anche ciò che è interessante da leggere (trattando anche gli argomenti sopra menzionati) sono gli articoli della Guida JavaScript di MDN :

  • Una re-introduzione a JavaScript
  • Lavorare con gli oggetti

Se vuoi sapere come emulare out parametri di c # out (come in DateTime.TryParse(str, out result) ) in JavaScript, puoi trovare il codice di esempio qui.


Chi di voi sta lavorando con IE (che non ha console per JavaScript a meno che non si aprano gli strumenti di sviluppo usando F12 e si apra la scheda della console) potrebbe trovare utile il seguente frammento. Ti permette di usare console.log(msg); come usato negli esempi sopra. Basta inserirlo prima della funzione Podcast .

Per comodità, ecco il codice sopra in uno snippet di codice singolo completo:

 let console = { log: function(msg) { let canvas = document.getElementById("log"), br = canvas.innerHTML==="" ? "" : "
"; canvas.innerHTML += (br + (msg || "").toString()); }}; console.log('For details, see the explaining text'); function Podcast() { // with this, you can instantiate without new (see description in text) if (false === (this instanceof Podcast)) { return new Podcast(); } // private variables var _somePrivateVariable = 123; // object properties this.title = 'Astronomy Cast'; this.description = 'A fact-based journey through the galaxy.'; this.link = 'http://www.astronomycast.com'; this.immutableProp = function() { return _somePrivateVariable; } // object function this.toString = function() { return 'Title: ' + this.title; } }; // static property Podcast.FILE_EXTENSION = 'mp3'; // static function Podcast.download = function(podcast) { console.log('Downloading ' + podcast + ' ...'); }; // access static properties/functions Podcast.FILE_EXTENSION; // 'mp3' Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...' // access object properties/functions var podcast = new Podcast(); podcast.title = 'The Simpsons'; console.log(podcast.toString()); // Title: The Simpsons console.log(podcast.immutableProp()); // 123 // getters and setters var d = Date.prototype; Object.defineProperty(d, "year", { get: function() { return this.getFullYear() }, set: function(y) { this.setFullYear(y) } }); // getters and setters - alternative syntax var obj = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2 } }; // usage: console.log(obj.a); console.log(obj.b); // output: 7, 8 obj.c=40; console.log(obj.a); console.log(obj.b); // output: 20, 21 var a=new Podcast(); var b=new Podcast(); a.title="a"; b.title="An "+b.title; console.log(a.title); // "a" console.log(b.title); // "An Astronomy Cast" Podcast.prototype.titleAndLink = function() { return this.title + " [" + this.link + "]"; }; console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]" console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
 

Risposta aggiornata:

In ECMAScript 6 , puoi creare funzioni statiche usando la parola chiave static :

 class Foo { static bar() {return 'I am static.'} } //`bar` is a property of the class Foo.bar() // returns 'I am static.' //`bar` is not a property of instances of the class var foo = new Foo() foo.bar() //-> throws TypeError 

Le classi ES6 non introducono alcuna nuova semantica per la statistica. Puoi fare la stessa cosa in ES5 in questo modo:

 //constructor var Foo = function() {} Foo.bar = function() { return 'I am static.' } Foo.bar() // returns 'I am static.' var foo = new Foo() foo.bar() // throws TypeError 

È ansible assegnare a una proprietà di Foo perché le funzioni JavaScript sono oggetti.

Il seguente esempio e spiegazione sono tratti dal libro Professional JavaScript for Web Developers 2nd Edition di Nicholas Zakas. Questa è la risposta che stavo cercando, quindi ho pensato che sarebbe stato utile aggiungerla qui.

 (function () { var name = ''; Person = function (value) { name = value; }; Person.prototype.getName = function () { return name; }; Person.prototype.setName = function (value) { name = value; }; }()); var person1 = new Person('Nate'); console.log(person1.getName()); // Nate person1.setName('James'); console.log(person1.getName()); // James person1.name = 'Mark'; console.log(person1.name); // Mark console.log(person1.getName()); // James var person2 = new Person('Danielle'); console.log(person1.getName()); // Danielle console.log(person2.getName()); // Danielle 

Il costruttore Person in questo esempio ha accesso al nome della variabile privata, così come i metodi getName() e setName() . Usando questo modello, la variabile name diventa statica e verrà utilizzata tra tutte le istanze. Ciò significa che chiamare setName() su un’istanza ha effetto su tutte le altre istanze. Chiamando setName() o creando una nuova istanza Person la variabile name viene impostata su un nuovo valore. Ciò fa sì che tutte le istanze restituiscano lo stesso valore.

Se stai usando la nuova syntax della class, ora puoi fare quanto segue:

  class MyClass { static get myStaticVariable() { return "some static variable"; } } console.log(MyClass.myStaticVariable); aMyClass = new MyClass(); console.log(aMyClass.myStaticVariable, "is undefined"); 

Se si desidera dichiarare variabili statiche per la creazione di costanti nell’applicazione, ho trovato il seguente approccio semplicistico

 ColorConstants = (function() { var obj = {}; obj.RED = 'red'; obj.GREEN = 'green'; obj.BLUE = 'blue'; obj.ALL = [obj.RED, obj.GREEN, obj.BLUE]; return obj; })(); //Example usage. var redColor = ColorConstants.RED; 

Informazioni sulla class introdotta da ECMAScript 2015. Le altre risposte non sono completamente chiare.

Ecco un esempio che mostra come creare una staticVar statica con ClassName . var synthax:

 class MyClass { constructor(val) { this.instanceVar = val; MyClass.staticVar = 10; } } var class1 = new MyClass(1); console.log(class1.instanceVar); // 1 console.log(class1.constructor.staticVar); // 10 // New instance of MyClass with another value var class2 = new MyClass(3); console.log(class1.instanceVar); // 1 console.log(class2.instanceVar); // 3 

Per accedere alla variabile statica usiamo la proprietà .constructor che restituisce un riferimento alla funzione di costruzione dell’object che ha creato la class. Possiamo chiamarlo sulle due istanze create:

 MyClass.staticVar = 11; console.log(class1.constructor.staticVar); // 11 console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :) MyClass.staticVar = 12; console.log(class1.constructor.staticVar); // 12 console.log(class2.constructor.staticVar); // 12 

Ci sono altre risposte simili, ma nessuna di esse mi ha attratto molto. Ecco cosa ho finito con:

 var nextCounter = (function () { var counter = 0; return function() { var temp = counter; counter += 1; return temp; }; })(); 

Puoi creare una variabile statica in JavaScript come questa di seguito. Qui count è la variabile statica.

 var Person = function(name) { this.name = name; // first time Person.count is undefined, so it is initialized with 1 // next time the function is called, the value of count is incremented by 1 Person.count = Person.count ? Person.count + 1 : 1; } var p1 = new Person('User p1'); console.log(p1.constructor.count); // prints 1 var p2 = new Person('User p2'); console.log(p2.constructor.count); // prints 2 

È ansible assegnare valori alla variabile statica utilizzando la funzione Person o una delle istanze:

 // set static variable using instance of Person p1.constructor.count = 10; // this change is seen in all the instances of Person console.log(p2.constructor.count); // prints 10 // set static variable using Person Person.count = 20; console.log(p1.constructor.count); // prints 20 

Se si desidera creare una variabile statica globale:

 var my_id = 123; 

Sostituisci la variabile con il seguente:

 Object.defineProperty(window, 'my_id', { get: function() { return 123; }, configurable : false, enumerable : false }); 

In JavaScript le variabili sono statiche per impostazione predefinita. Esempio :

 var x = 0;

 funzione draw () {
     alert (x);  //
     x + = 1;
 }

 setInterval (draw, 1000);

Il valore di x viene incrementato di 1 ogni 1000 millisecondi
Stamperà 1,2,3 così via

La cosa più vicina in JavaScript a una variabile statica è una variabile globale – questa è semplicemente una variabile dichiarata al di fuori dell’ambito di una funzione o di un object letterale:

 var thisIsGlobal = 1; function foo() { var thisIsNot = 2; } 

L’altra cosa che potresti fare sarebbe memorizzare le variabili globali all’interno di un object letterale come questo:

 var foo = { bar : 1 } 

E poi accedi ai vari veicoli come questo: foo.bar .

C’è un altro approccio, che ha risolto i miei requisiti dopo aver sfogliato questo thread. Dipende esattamente da cosa vuoi ottenere con una “variabile statica”.

La proprietà globale sessionStorage o localStorage consente di archiviare i dati per la durata della sessione o per un periodo più lungo indefinito fino a quando non vengono esplicitamente deselezionati, rispettivamente. Ciò consente di condividere i dati tra tutte le windows, i frame, i pannelli a tabs, i popup, ecc. Della tua pagina / app ed è molto più potente di una semplice “variabile statica / globale” in un segmento di codice.

Evita ogni problema con l’ambito, la durata, la semantica, la dynamic, ecc. Delle variabili globali di alto livello, ad esempio Window.myglobal. Non so quanto sia efficiente, ma non è importante per quantità modeste di dati, accessibili a prezzi modesti.

Facilmente accessibile come “sessionStorage.mydata = qualsiasi cosa” e recuperato in modo simile. Vedi “JavaScript: la guida definitiva, sesta edizione”, David Flanagan, ISBN: 978-0-596-80552-4, capitolo 20, sezione 20.1. Questo è facilmente scaricabile in formato PDF con una semplice ricerca o nel tuo abbonamento a O’Reilly Safaribooks (vale il suo peso in oro).

Saluti, Greg E

Per condensare tutti i concetti di class qui, prova questo:

 var Test = function() { // "super private" variable, accessible only here in constructor. There are no real private variables //if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classs var test_var = "super private"; //the only way to access the "super private" test_var is from here this.privileged = function(){ console.log(test_var); }(); Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classs this.init(); };//end constructor Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below) Test.prototype = { init:function(){ console.log('in',Test.test_var); } };//end prototype/class //for example: $(document).ready(function() { console.log('out',Test.test_var); var Jake = function(){} Jake.prototype = new Test(); Jake.prototype.test = function(){ console.log('jake', Test.test_var); } var jake = new Jake(); jake.test();//output: "protected" });//end domready 

Bene, un altro modo per dare un’occhiata alle migliori pratiche in queste cose, è solo vedere come il coffeescript traduce questi concetti.

 #this is coffeescript class Test #static @prop = "static" #instance constructor:(prop) -> @prop = prop console.log(@prop) t = new Test('inst_prop'); console.log(Test.prop); //this is how the above is translated in plain js by the CS compiler Test = (function() { Test.prop = "static"; function Test(prop) { this.prop = prop; console.log(this.prop); } return Test; })(); t = new Test('inst_prop'); console.log(Test.prop); 

Oltre al resto, c’è attualmente una bozza (proposta stage-2 ) su proposte ECMA che introduce campi pubblici static nelle classi. ( i campi privati ​​erano considerati )

Utilizzando l’esempio della proposta, la syntax static proposta sarà simile a questa:

 class CustomDate { // ... static epoch = new CustomDate(0); } 

ed essere equivalente al seguente che altri hanno evidenziato:

 class CustomDate { // ... } CustomDate.epoch = new CustomDate(0); 

È quindi ansible accedervi tramite CustomDate.epoch .

Puoi tenere traccia della nuova proposta nelle proposal-static-class-features della proposal-static-class-features .


Attualmente, Babel supporta questa funzionalità con il plugin delle proprietà della class di trasformazione che è ansible utilizzare. Inoltre, anche se ancora in corso, V8 sta implementando .

In JavaScript, non ci sono termini o parole chiave statici, ma possiamo mettere tali dati direttamente nell’object funzione (come in qualsiasi altro object).

 function f() { f.count = ++f.count || 1 // f.count is undefined at first alert("Call No " + f.count) } f(); // Call No 1 f(); // Call No 2 

Le funzioni / classi consentono solo un singolo costruttore per il suo ambito object. Function Hoisting, declarations & expressions

  • Le funzioni create con il costruttore Function non creano chiusure ai loro contesti di creazione; sono sempre creati nell’ambito globale.

      var functionClass = function ( ) { var currentClass = Shape; _inherits(currentClass, superClass); function functionClass() { superClass.call(this); // Linking with SuperClass Constructor. // Instance Variables list. this.id = id; return this; } }(SuperClass) 

Chiusure : le copie della chiusura funzionano con dati conservati.

  • Le copie di ogni chiusura vengono create per una funzione con i propri valori o riferimenti gratuiti. Ogni volta che si utilizza la funzione all’interno di un’altra funzione, viene utilizzata una chiusura.
  • Una chiusura in JavaScript è come mantenere una copia di tutte le variabili locali della sua funzione genitore da innerFunctions.

      function closureFun( args ) { // Local variable that ends up within closure var num = args; num++; return function() { console.log(num); } } var closure1 = closureFun( 5 ); var closure2 = closureFun( 777 ); closure1(); // 5 closure2(); // 777 closure2(); // 778 closure1(); // 6 

Classi di funzioni ES5 : utilizza Object.defineProperty (O, P, Attributes)

Il metodo Object.defineProperty () definisce una nuova proprietà direttamente su un object o modifica una proprietà esistente su un object e restituisce l’object.

Abbiamo creato alcuni metodi usando “ , in modo che ogni volta sia ansible capire facilmente le classi di funzioni.

 'use strict'; var Shape = function ( superClass ) { var currentClass = Shape; _inherits(currentClass, superClass); // Prototype Chain - Extends function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor. // Instance Variables list. this.id = id; return this; } var staticVariablesJOSN = { "parent_S_V" : 777 }; staticVariable( currentClass, staticVariablesJOSN ); // Setters, Getters, instanceMethods. [{}, {}]; var instanceFunctions = [ { key: 'uniqueID', get: function get() { return this.id; }, set: function set(changeVal) { this.id = changeVal; } } ]; instanceMethods( currentClass, instanceFunctions ); return currentClass; }(Object); var Rectangle = function ( superClass ) { var currentClass = Rectangle; _inherits(currentClass, superClass); // Prototype Chain - Extends function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor. this.width = width; this.height = height; return this; } var staticVariablesJOSN = { "_staticVar" : 77777 }; staticVariable( currentClass, staticVariablesJOSN ); var staticFunctions = [ { key: 'println', value: function println() { console.log('Static Method'); } } ]; staticMethods(currentClass, staticFunctions); var instanceFunctions = [ { key: 'setStaticVar', value: function setStaticVar(staticVal) { currentClass.parent_S_V = staticVal; console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V); } }, { key: 'getStaticVar', value: function getStaticVar() { console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V); return currentClass.parent_S_V; } }, { key: 'area', get: function get() { console.log('Area : ', this.width * this.height); return this.width * this.height; } }, { key: 'globalValue', get: function get() { console.log('GET ID : ', currentClass._staticVar); return currentClass._staticVar; }, set: function set(value) { currentClass._staticVar = value; console.log('SET ID : ', currentClass._staticVar); } } ]; instanceMethods( currentClass, instanceFunctions ); return currentClass; }(Shape); // ===== ES5 Class Conversion Supported Functions ===== function defineProperties(target, props) { console.log(target, ' : ', props); for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function staticMethods( currentClass, staticProps ) { defineProperties(currentClass, staticProps); }; function instanceMethods( currentClass, protoProps ) { defineProperties(currentClass.prototype, protoProps); }; function staticVariable( currentClass, staticVariales ) { // Get Key Set and get its corresponding value. // currentClass.key = value; for( var prop in staticVariales ) { console.log('Keys : Values'); if( staticVariales.hasOwnProperty( prop ) ) { console.log(prop, ' : ', staticVariales[ prop ] ); currentClass[ prop ] = staticVariales[ prop ]; } } }; function _inherits(subClass, superClass) { console.log( subClass, ' : extends : ', superClass ); if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 

Below code snippet is to test about Each instance has their own copy of instance members and common static members.

 var objTest = new Rectangle('Yash_777', 8, 7); console.dir(objTest); var obj1 = new Rectangle('R_1', 50, 20); Rectangle.println(); // Static Method console.log( obj1 ); // Rectangle {id: "R_1", width: 50, height: 20} obj1.area; // Area : 1000 obj1.globalValue; // GET ID : 77777 obj1.globalValue = 88; // SET ID : 88 obj1.globalValue; // GET ID : 88 var obj2 = new Rectangle('R_2', 5, 70); console.log( obj2 ); // Rectangle {id: "R_2", width: 5, height: 70} obj2.area; // Area : 350 obj2.globalValue; // GET ID : 88 obj2.globalValue = 999; // SET ID : 999 obj2.globalValue; // GET ID : 999 console.log('Static Variable Actions.'); obj1.globalValue; // GET ID : 999 console.log('Parent Class Static variables'); obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 777 obj1.setStaticVar(7); // SET Instance Method Parent Class Static Value : 7 obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 7 

Static method calls are made directly on the class and are not callable on instances of the class. But you can achieve the calls for static members from inside an instance.

Using syntax:

  this.constructor.staticfunctionName(); 
 class MyClass { constructor() {} static staticMethod() { console.log('Static Method'); } } MyClass.staticVar = 777; var myInstance = new MyClass(); // calling from instance myInstance.constructor.staticMethod(); console.log('From Inside Class : ',myInstance.constructor.staticVar); // calling from class MyClass.staticMethod(); console.log('Class : ', MyClass.staticVar); 

ES6 Classes: ES2015 classs are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.

Example : refer my previous post.

There are 4 ways to emulate function-local static variables in Javascript.

Method 1: Using function object properties (supported in old browsers)

 function someFunc1(){ if( !('staticVar' in someFunc1) ) someFunc1.staticVar = 0 ; alert(++someFunc1.staticVar) ; } someFunc1() ; //prints 1 someFunc1() ; //prints 2 someFunc1() ; //prints 3 

Method 2: Using a closure, variant 1 (supported in old browsers)

 var someFunc2 = (function(){ var staticVar = 0 ; return function(){ alert(++staticVar) ; } })() someFunc2() ; //prints 1 someFunc2() ; //prints 2 someFunc2() ; //prints 3 

Method 3: Using a closure, variant 2 (also supported in old browsers)

 var someFunc3 ; with({staticVar:0}) var someFunc3 = function(){ alert(++staticVar) ; } someFunc3() ; //prints 1 someFunc3() ; //prints 2 someFunc3() ; //prints 3 

Method 4: Using a closure, variant 3 (requires support for EcmaScript 2015)

 { let staticVar = 0 ; function someFunc4(){ alert(++staticVar) ; } } someFunc4() ; //prints 1 someFunc4() ; //prints 2 someFunc4() ; //prints 3 

Window level vars are sorta like statics in the sense that you can use direct reference and these are available to all parts of your app

There is no such thing as an static variable in Javascript. This language is prototype-based object orientated, so there are no classs, but prototypes from where objects “copy” themselves.

You may simulate them with global variables or with prototyping (adding a property to the prototype):

 function circle(){ } circle.prototype.pi=3.14159 

Working with MVC websites that use jQuery, I like to make sure AJAX actions within certain event handlers can only be executed once the previous request has completed. I use a “static” jqXHR object variable to achieve this.

Given the following button:

  

I generally use an IIFE like this for my click handler:

 var ajaxAction = (function (jqXHR) { return function (sender, args) { if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) { jqXHR = $.ajax({ url: args.url, type: 'POST', contentType: 'application/json', data: JSON.stringify($(sender).closest('form').serialize()), success: function (data) { // Do something here with the data. } }); } }; })(null); 

If you want to use prototype then there is a way

 var p = function Person() { this.x = 10; this.y = 20; } p.prototype.counter = 0; var person1 = new p(); person1.prototype = p.prototype; console.log(person1.counter); person1.prototype.counter++; var person2 = new p(); person2.prototype = p.prototype; console.log(person2.counter); console.log(person1.counter); 

Doing this you will be able to access the counter variable from any instance and any change in the property will be immediately reflected!!

So what I see with the other answers is that they don’t address the fundamental architectural requirement of a static attribute in object oriented programming.

Object oriented programming actually has two different styles one is ‘class based’ (C++, C#, Java etc), the other is ‘prototypal’ (Javascript). In class based languages a ‘static attribute’ is supposed to be associated with the class and not the instantiated objects. This concept actually works much more intuitively in a prototypal languages like Javascript because you just assign the attribute as a value of the parent prototype like so.

 function MyObject() {}; MyObject.prototype.staticAttribute = "some value"; 

And access it from every one of the objects that is instantiated from this constructor like so…

 var childObject1 = new MyObject(); // Instantiate a child object var childObject2 = new MyObject(); // Instantiate another child object console.log(childObject.staticAttribute); // Access the static Attribute from child 1 console.log(childObject.staticAttribute); // Access the static Attribute from child 2 

Now if you go ahead and change the MyObject.prototype.staticAttribute the change will cascade down to the child objects that immediately inherit it.

However there are a few ‘gotchas’ that could significantly undermine the ‘static’ nature of this attribute, or just leave security vulnerability…

First make sure to hide the constructor from the Global namespace by enclosing it inside another function like the jQuery ready method

  $(document).ready(function () { function MyObject() { // some constructor instructions }; MyObject.prototype.staticAttribute = "some value"; var childObject = new MyObject(); // instantiate child object console.log(childObject.staticAttribute); // test attribute }); 

Second and lastly, even if you do this, the attribute is still editable from any of the other parts of your own script, so it could be the case that a bug in your code writes over the attribute on one of the child objects and detaches it from the parent prototype, so if you change the parent attribute it will no longer cascade and change the static attribute for the child object. See this jsfiddle. In different scenarios we could either Object.freeze(obj) to stop any changes to the child object, or we could set up a setter and getter method in the constructor and access a closure, both of these have associated complexities.

It seems to me that there is not a perfect analogue between the class-based idea of a ‘static attribute’ and this Javascript implementation. So I think it might be better in the long run to use a different code pattern that is more Javascript friendly. Such as a central datastore or cache or even a dedicated helper object to hold all the necessary static variables.

I didn’t see this idea in any of the answers so just adding it to the list. If it’s a duplicate just let me know and i’ll delete it and upvote the other.

I created a sort of super global in my website. Since I have several js files that are loaded on every page load and dozens of other js files that are only loaded on some pages I put all of the “global” function into a single global variable.

At the top of my first included “global” files is the declaration

 var cgf = {}; // Custom global functions. 

Then I delcare several global helper functions

 cgf.formBehaviors = function() { // My form behaviors that get attached in every page load. } 

Then if I need a static variable I just store it outside scope such as outside the document ready or outside the behavior attachment. (I use jquery but it should work in javascript)

 cgf.first = true; $.on('click', '.my-button', function() { // Don't allow the user to press the submit twice. if (cgf.first) { // first time behavior. such as submit } cgf.first = false; } 

This of course is a global not a static but as it is reinitialized on every page load it accomplishes the same purpose.

For private static variables, I found this way:

 function Class() { } Class.prototype = new function() { _privateStatic = 1; this.get = function() { return _privateStatic; } this.inc = function() { _privateStatic++; } }; var o1 = new Class(); var o2 = new Class(); o1.inc(); console.log(o1.get()); console.log(o2.get()); // 2 

Prova questo:

If we define a property and override its getters and setters to use the Function Object property then in theory you can have an static variable in javascript

per esempio:

 function Animal() { if (isNaN(this.totalAnimalCount)) { this.totalAnimalCount = 0; } this.totalAnimalCount++; }; Object.defineProperty(Animal.prototype, 'totalAnimalCount', { get: function() { return Animal['totalAnimalCount']; }, set: function(val) { Animal['totalAnimalCount'] = val; } }); var cat = new Animal(); console.log(cat.totalAnimalCount); //Will produce 1 var dog = new Animal(); console.log(cat.totalAnimalCount); //Will produce 2 and so on.