Variáveis ​​estáticas em JavaScript

Como posso criar variables ​​estáticas em JavaScript?

Se você vem de uma linguagem orientada a object, baseada em class e estaticamente datilografada (como Java, C ++ ou C #) , presumo que você esteja tentando criar uma variável ou método associado a um “tipo”, mas não a uma instância.

Um exemplo usando uma abordagem “clássica”, com funções construtoras, pode ajudá-lo a capturar os conceitos básicos do JavaScript OO:

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 é definido no object MyClass (que é uma function) e não tem nada a ver com suas instâncias criadas, o JavaScript trata funções como objects de primeira class , portanto, sendo um object, você pode atribuir propriedades a uma function.

Você pode aproveitar o fato de que as funções JS também são objects – o que significa que elas podem ter propriedades.

Por exemplo, citando o exemplo dado no artigo (agora desaparecido) Variáveis ​​estáticas em 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 você chamar essa function várias vezes, verá que o contador está sendo incrementado.

E esta é provavelmente uma solução muito melhor do que poluir o namespace global com uma variável global.

E aqui está outra solução possível, baseada em um fechamento: Truque para usar variables ​​estáticas em 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. 

O que te dá o mesmo tipo de resultado – exceto que, desta vez, o valor incrementado é retornado, ao invés de exibido.

Você faz isso através de um IIFE (expressão de function invocada imediatamente):

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

você pode usar arguments.callee para armazenar variables ​​”estáticas” (isso também é útil em function anônima):

 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(); 

Eu vi algumas respostas semelhantes, mas gostaria de mencionar que este post descreve melhor, então eu gostaria de compartilhar com você.

Aqui está um código extraído dele, que modifiquei para obter um exemplo completo que, espera-se, traga benefícios para a comunidade, pois ele pode ser usado como um modelo de design para classs.

Ele também responde à sua pergunta:

 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 + ' ...'); }; 

Dado esse exemplo, você pode alcançar as propriedades / function estáticas como segue:

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

E as propriedades / funções do object simplesmente como:

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

Observe que em podcast.immutableProp (), temos um fechamento : A referência a _somePrivateVariable é mantida dentro da function.

Você pode até definir getters e setters . Dê uma olhada neste snippet de código (onde d é o protótipo do object para o qual você deseja declarar uma propriedade, y é uma variável privada não visível fora do construtor):

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

Ele define a propriedade d.year por meio das funções get e set – se você não especificar set , a propriedade será somente leitura e não poderá ser modificada (esteja ciente de que você não obterá um erro se tentar configurá-lo, mas não tem efeito). Cada propriedade tem os atributos writable , configurable (permite alterar após a declaração) e enumerable (permite usá-lo como enumerador), que por padrão são false . Você pode defini-los via defineProperty no 3º parâmetro, por exemplo enumerable: true .

O que também é válido é esta syntax:

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

que define uma propriedade legível / gravável a , uma propriedade readonly b e uma propriedade somente de gravação c , através da qual a propriedade a pode ser acessada.

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 

Notas:

Para evitar comportamentos inesperados caso você tenha esquecido a new palavra-chave, sugiro que adicione o seguinte à function Podcast :

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

Agora, as duas instanciações a seguir funcionarão conforme o esperado:

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

A instrução ‘new’ cria um novo object e copia todas as propriedades e methods, ou seja,

 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" 

Observe também que , em algumas situações, pode ser útil usar a instrução de return na function de construtor Podcast para retornar um object personalizado que protege as funções nas quais a class confia internamente, mas que precisam ser expostas. Isso é explicado mais adiante no capítulo 2 (Objetos) da série de artigos.

Você pode dizer que b herda do Podcast . Agora, e se você quiser adicionar um método ao Podcast que se aplique a todos eles depois de b ter sido instanciado? Nesse caso, use o .prototype seguinte maneira:

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

Agora chame a e b novamente:

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

Você pode encontrar mais detalhes sobre protótipos aqui . Se você quiser fazer mais inheritance, sugiro olhar para isso .


A série de artigos que mencionei acima é altamente recomendada para leitura, incluindo também os seguintes tópicos:

  1. Funções
  2. Objetos
  3. Protótipos
  4. Reforçando Novas Funções do Construtor
  5. Elevação
  6. Inserção automática de ponto e vírgula
  7. Propriedades estáticas e methods

Observe que o “recurso” automático de inserção de ponto-e-vírgula do JavaScript (como mencionado em 6.) é muitas vezes responsável por causar problemas estranhos em seu código. Por isso, prefiro considerá-lo como um bug do que como um recurso.

Se você quiser ler mais, aqui está um artigo do MSDN bastante interessante sobre esses tópicos, alguns deles descritos fornecem ainda mais detalhes.

O que é interessante ler também (também cobrindo os tópicos mencionados acima) são aqueles artigos do Guia JavaScript MDN :

  • Uma re-introdução ao JavaScript
  • Trabalhando com Objetos

Se você quiser saber como emular out parâmetros c # out (como em DateTime.TryParse(str, out result) ) em JavaScript, você pode encontrar o código de exemplo aqui.


Aqueles de vocês que estão trabalhando com o IE (que não tem console para JavaScript, a menos que você abra as ferramentas do desenvolvedor usando F12 e abra a guia do console) podem achar útil o trecho a seguir. Ele permite que você use o console.log(msg); como usado nos exemplos acima. Basta inseri-lo antes da function Podcast .

Para sua conveniência, aqui está o código acima em um único snippet de código 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]"
 

Resposta atualizada:

No ECMAScript 6 , você pode criar funções estáticas usando a palavra-chave 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 

As classs ES6 não introduzem nenhuma nova semântica para estática. Você pode fazer a mesma coisa no ES5 assim:

 //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 

Você pode atribuir a uma propriedade de Foo porque em funções JavaScript são objects.

O exemplo e a explicação a seguir são do livro Professional JavaScript for Web Developers, segunda edição de Nicholas Zakas. Esta é a resposta que eu estava procurando, então eu pensei que seria útil adicioná-lo aqui.

 (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 

O construtor Person neste exemplo tem access ao nome da variável privada, assim como os methods getName() e setName() . Usando esse padrão, a variável de nome se torna estática e será usada entre todas as instâncias. Isso significa que chamar setName() em uma instância afeta todas as outras instâncias. Chamar setName() ou criar uma nova instância Person define a variável name como um novo valor. Isso faz com que todas as instâncias retornem o mesmo valor.

Se você estiver usando a nova syntax de class , poderá agora fazer o seguinte:

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

Se você quiser declarar variables ​​estáticas para criar constantes em sua aplicação, então eu encontrei seguindo como abordagem mais simplista

 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; 

Sobre a class introduzida pelo ECMAScript 2015. As outras respostas não são totalmente claras.

Aqui está um exemplo mostrando como criar um static static var var com o 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 

Para acessar a variável estática, usamos a propriedade .constructor que retorna uma referência à function construtora do object que criou a class. Podemos chamá-lo nas duas instâncias criadas:

 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 

Há outras respostas semelhantes, mas nenhuma delas me atraiu. Aqui está o que acabei com:

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

Você pode criar uma variável estática em JavaScript como esta abaixo. Aqui count é a variável estática.

 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 

Você pode atribuir valores à variável estática usando a function Person ou qualquer uma das instâncias:

 // 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 você quisesse criar uma variável estática global:

 var my_id = 123; 

Substitua a variável com o abaixo:

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

Em JavaScript, as variables ​​são estáticas por padrão. Exemplo :

 var x = 0;

 function draw () {
     alerta (x);  //
     x + = 1;
 }

 setInterval (desenho, 1000);

O valor de x é incrementado em 1 a cada 1000 milissegundos
Ele irá imprimir 1,2,3 assim por diante

A coisa mais próxima em JavaScript para uma variável estática é uma variável global – isso é simplesmente uma variável declarada fora do escopo de uma function ou literal de object:

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

A outra coisa que você poderia fazer seria armazenar variables ​​globais dentro de um literal de object como este:

 var foo = { bar : 1 } 

E então acesse as variables ​​como: foo.bar .

Há outra abordagem, que resolveu meus requisitos depois de navegar neste segmento. Depende exatamente do que você deseja alcançar com uma “variável estática”.

A propriedade global sessionStorage ou localStorage permite que os dados sejam armazenados durante a vida útil da session ou por um período mais longo indefinidamente até que sejam explicitamente limpos, respectivamente. Isso permite que os dados sejam compartilhados entre todas as janelas, frameworks, painéis de abas, pop-ups etc de sua página / aplicativo e é muito mais poderoso do que uma simples “variável estática / global” em um segmento de código.

Ele evita todos os problemas com o escopo, a vida útil, a semântica, a dinâmica, etc. de variables ​​globais de nível superior, ou seja, Window.myglobal. Não sei quão eficiente é, mas isso não é importante para quantidades modestas de dados, acessadas a taxas modestas.

Facilmente acessado como “sessionStorage.mydata = anything” e recuperado de forma semelhante. Veja “JavaScript: O Guia Definitivo, Sexta Edição”, David Flanagan, ISBN: 978-0-596-80552-4, Capítulo 20, seção 20.1. Isso pode ser facilmente baixado como um PDF por simples pesquisa, ou em sua assinatura da O’Reilly Safaribooks (que vale seu peso em ouro).

Felicidades, Greg E

Para condensar todos os conceitos de class aqui, teste isso:

 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 

Bem, outra maneira de ver as melhores práticas nessas coisas é apenas ver como o coffeescript traduz esses conceitos.

 #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); 

Além do restante, há atualmente um rascunho (proposta do estágio 2 ) em Propostas ECMA, que introduz campos públicos static nas classs. ( campos privados foram considerados )

Usando o exemplo da proposta, a syntax static proposta terá a seguinte aparência:

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

e ser equivalente ao seguinte que outros destacaram:

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

Você pode acessá-lo via CustomDate.epoch .

Você pode acompanhar a nova proposta em proposal-static-class-features .


Atualmente, o babel suporta este recurso com o plugin de propriedades da class de transformação que você pode usar. Além disso, embora ainda em andamento, o V8 está implementando-o .

Em JavaScript, não há termo ou palavra-chave estática, mas podemos colocar esses dados diretamente no object de function (como em qualquer outro 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 

Funções / classs permite apenas um único construtor para o seu escopo de object. Function Hoisting, declarations & expressions

  • Funções criadas com o construtor Function não criam fechamentos para seus contextos de criação; eles sempre são criados no escopo global.

      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) 

Fechamentos – as cópias do fechamento são function com dados preservados.

  • As cópias de cada fechamento são criadas para uma function com seus próprios valores livres ou referências, sempre que você usa a function dentro de outra function, um fechamento é usado.
  • Um encerramento em JavaScript é como manter uma cópia de todas as variables ​​locais de sua function pai pelo 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 

Classes de Função ES5 : usa Object.defineProperty (O, P, Attributes)

O método Object.defineProperty () define uma nova propriedade diretamente em um object ou modifica uma propriedade existente em um object e retorna o object.

Criado alguns methods usando “ , para que de uma vez possa entender as classs de function facilmente.

 '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 

Tente este:

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

por exemplo:

 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.