Como posso criar variáveis estáticas em Javascript?
javascript
variables
static
closures
Rajat
fonte
fonte
someFunc = () => { MyClass.myStaticVariable = 1; }
. Em seguida, basta criar um método estático para retornar o membro estático, por exemplostatic getStatic() { return MyClass.myStaticVariable; }
. Então você pode simplesmente ligarMyClass.getStatic()
de fora da classe para se apossar dos dados estáticos!Respostas:
Se você vem de uma linguagem orientada a objeto com base em classe e estaticamente tipada (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 de construtor, talvez possa ajudá-lo a entender os conceitos básicos do JavaScript OO:
staticProperty
é definido no objeto MyClass (que é uma função) e não tem nada a ver com suas instâncias criadas, o JavaScript trata as funções como objetos de primeira classe ; portanto, sendo um objeto, você pode atribuir propriedades a uma função.ATUALIZAÇÃO: O ES6 introduziu a capacidade de declarar classes por meio da
class
palavra - chave. É açúcar de sintaxe sobre a herança baseada em protótipo existente.A
static
palavra-chave permite definir facilmente propriedades ou métodos estáticos em uma classe.Vamos ver o exemplo acima implementado com as classes ES6:
fonte
privilegedMethod
não é equivalente a um método privado no OO porque parece que poderia ser chamado em uma instância do MyClass? Você quer dizer que é privilegiado porque pode acessarprivateVariable
?this.constructor
ser usado para acessar as variáveis estáticas de "métodos de instância"? Se sim, vale a pena adicioná-lo à resposta.MyClass.prototype.staticProperty = "baz";
ou ser ainda mais correto para os princípios de OO, a propriedade estática deve realmente ser definida como uma função anônimaMyClass.prototype.staticProperty = function () {return staticVar;}
e para que todas as instâncias acessem uma única variável que também possa ser alterada com um setter.Você pode aproveitar o fato de que as funções JS também são objetos - o que significa que elas podem ter propriedades.
Por exemplo, citando o exemplo dado no artigo (agora desaparecido) Variáveis estáticas em Javascript :
Se você chamar essa função várias vezes, verá que o contador está sendo incrementado.
E esta é provavelmente uma solução muito melhor do que poluir o espaço para nome global com uma variável global.
E aqui está outra solução possível, com base em um fechamento: Truque para usar variáveis estáticas em javascript :
O que gera o mesmo tipo de resultado - exceto que, desta vez, o valor incrementado é retornado, em vez de exibido.
fonte
countMyself.counter = countMyself.counter || initial_value;
se a variável estática não vai ser Falsey (false, 0, null ou string vazia)===
paratypeof
verificações, caso contrário você terá uma coerção estranha.Você faz isso através de um IIFE (expressão de função imediatamente chamada):
fonte
você pode usar o argumento.callee para armazenar variáveis "estáticas" (isso também é útil na função anônima):
fonte
arguments.callee
está obsoleto.callee
parecia uma coisa agradável de se ter. Gostaria de saber por que o hack eles decidiram depreciar isso ...: |Vi algumas respostas semelhantes, mas gostaria de mencionar que este post descreve melhor, por isso, gostaria de compartilhar com você.
Aqui estão alguns códigos retirados dele, que modifiquei para obter um exemplo completo que, esperamos, traga benefícios à comunidade, pois pode ser usado como um modelo de design para as classes.
Ele também responde à sua pergunta:
Dado esse exemplo, você pode acessar as propriedades / funções estáticas da seguinte maneira:
E as propriedades / funções do objeto simplesmente como:
Observe que em podcast.immutableProp (), temos um fechamento : A referência a _somePrivateVariable é mantida dentro da função.
Você pode até definir getters e setters . Dê uma olhada neste snippet de código (onde
d
é o protótipo do objeto para o qual você deseja declarar uma propriedade,y
é uma variável privada não visível fora do construtor):Ele define a propriedade
d.year
viaget
eset
funções - se você não especificarset
, a propriedade é somente leitura e não pode ser modificada (lembre-se de que você não receberá um erro se tentar defini-la, mas não terá efeito). Cada propriedade tem os atributoswritable
,configurable
(permitir que a mudança após a declaração) eenumerable
(permitem usá-lo como recenseador), que são por padrãofalse
. Você pode configurá-los viadefineProperty
no terceiro parâmetro, por exemploenumerable: true
.O que também é válido é esta sintaxe:
que define uma propriedade legível / gravável
a
, uma propriedade somente leiturab
e uma propriedade somente gravaçãoc
, através da qual a propriedadea
pode ser acessada.Uso:
Notas:
Para evitar comportamentos inesperados, caso você tenha esquecido a
new
palavra - chave, sugiro que você adicione o seguinte à funçãoPodcast
:Agora, as duas instanciações a seguir funcionarão conforme o esperado:
A instrução 'new' cria um novo objeto e copia todas as propriedades e métodos, ou seja,
Observe também que , em algumas situações, pode ser útil usar a
return
instrução na função construtoraPodcast
para retornar um objeto personalizado que protege funções nas quais a classe confia internamente, mas que precisa ser exposta. Isso é explicado mais adiante no capítulo 2 (Objetos) da série de artigos.Você pode dizer isso
a
eb
herdar dePodcast
. Agora, e se você quiser adicionar ao Podcast um método que se aplique a todos eles depoisa
eb
tenha sido instanciado? Nesse caso, use o.prototype
seguinte:Agora ligue
a
eb
novamente:Você pode encontrar mais detalhes sobre protótipos aqui . Se você deseja fazer mais herança, sugiro investigar isso .
As séries de artigos que mencionei acima são altamente recomendadas para leitura, incluem também os seguintes tópicos:
Observe que o "recurso" automático de inserção de ponto e vírgula do JavaScript (conforme mencionado em 6.) é muitas vezes responsável por causar problemas estranhos no seu código. Por isso, prefiro considerá-lo um bug do que um recurso.
Se você quiser ler mais, aqui está um artigo interessante do MSDN sobre esses tópicos, alguns deles descritos aqui fornecem ainda mais detalhes.
O que é interessante de ler também (também abordando os tópicos mencionados acima) são os artigos do MDN JavaScript Guide :
Se você quiser saber como emular
out
parâmetros c # (como emDateTime.TryParse(str, out result)
) em JavaScript, poderá encontrar um exemplo de código aqui.Aqueles que estão trabalhando com o IE (que não tem console para JavaScript, a menos que você abra as ferramentas de desenvolvedor usando F12e abra a guia console) podem achar útil o seguinte trecho. Ele permite que você use
console.log(msg);
como usado nos exemplos acima. Basta inseri-lo antes daPodcast
função.Para sua conveniência, veja o código acima em um único trecho de código completo:
Mostrar snippet de código
Notas:
Algumas boas dicas, sugestões e recomendações sobre programação JavaScript em geral, você pode encontrar aqui (práticas recomendadas para JavaScript) e ali ('var' versus 'let') . Também é recomendado este artigo sobre previsões implícitas (coerção) .
Uma maneira conveniente de usar classes e compilá-las em JavaScript é o TypeScript. Aqui está um playground onde você pode encontrar alguns exemplos mostrando como funciona. Mesmo que você não esteja usando o TypeScript no momento, é possível ver porque você pode comparar o TypeScript com o resultado do JavaScript em uma exibição lado a lado. A maioria dos exemplos é simples, mas também há um exemplo do Raytracer que você pode experimentar instantaneamente. Eu recomendo olhar especialmente para os exemplos "Using Classes", "Using Inheritance" e "Using Generics" selecionando-os na caixa de combinação - esses são bons modelos que você pode usar instantaneamente em JavaScript. O texto datilografado é usado com Angular.
Para obter o encapsulamento de variáveis locais, funções etc. em JavaScript, sugiro usar um padrão como o seguinte (o JQuery usa a mesma técnica):
Obviamente, você pode - e deve - colocar o código do script em um
*.js
arquivo separado ; isso é apenas escrito em linha para manter o exemplo curto.As funções de auto-invocação (também conhecidas como IIFE = Expressão de Função Imediatamente Invocada) são descritas em mais detalhes aqui .
fonte
fonte
Resposta atualizada:
No ECMAScript 6 , você pode criar funções estáticas usando a
static
palavra-chave:As classes ES6 não introduzem nenhuma nova semântica para estática. Você pode fazer a mesma coisa no ES5 assim:
Você pode atribuir a uma propriedade de
Foo
porque, em funções JavaScript, são objetos.fonte
Foo.bar;
retorna a função atribuída a ele, não a sequência retornada pela função, como implica o seu comentário.bar
propriedadeFoo
da3
assim:Foo.bar = 3;
O exemplo e explicação a seguir são do livro Professional JavaScript for Web Developers 2nd Edition, de Nicholas Zakas. Esta é a resposta que eu estava procurando, então pensei que seria útil adicioná-la aqui.
O
Person
construtor neste exemplo tem acesso ao nome da variável privada, assim como os métodosgetName()
esetName()
. Usando esse padrão, a variável name se torna estática e será usada entre todas as instâncias. Isso significa que chamarsetName()
uma instância afeta todas as outras instâncias. ChamarsetName()
ou criar uma novaPerson
instância define a variável name para um novo valor. Isso faz com que todas as instâncias retornem o mesmo valor.fonte
Se você estiver usando a nova sintaxe de classe , poderá fazer o seguinte:
Isso efetivamente cria uma variável estática em JavaScript.
fonte
MyClass
definida fora da construção de classe.Se você deseja declarar variáveis estáticas para a criação de constantes em seu aplicativo, achei a seguir a abordagem mais simplista
fonte
Sobre o
class
introduzido pelo ECMAScript 2015. As outras respostas não são totalmente claras.Aqui está um exemplo mostrando como criar uma var estática
staticVar
com oClassName
.var
sintaxe:Para acessar a variável estática, usamos a
.constructor
propriedade que retorna uma referência à função construtora de objetos que criou a classe. Podemos chamá-lo nas duas instâncias criadas:fonte
Existem outras respostas semelhantes, mas nenhuma delas me atraiu. Aqui está o que eu acabei com:
fonte
Além do restante, atualmente há um rascunho (proposta da etapa 2 ) das propostas da ECMA que introduz campos
static
públicos nas aulas. ( campos particulares foram considerados )Usando o exemplo da proposta, a
static
sintaxe proposta terá a seguinte aparência:e ser equivalente ao seguinte, que outros destacaram:
Você pode acessá-lo via
CustomDate.epoch
.Você pode acompanhar a nova proposta em
proposal-static-class-features
.Atualmente, o babel suporta esse recurso com o plug-in de propriedades da classe de transformação que você pode usar. Além disso, embora ainda esteja em andamento,
V8
está implementando .fonte
Você pode criar uma variável estática em JavaScript como esta abaixo. Aqui
count
está a variável estática.Você pode atribuir valores à variável estática usando a
Person
função ou qualquer uma das instâncias:fonte
Se você deseja criar uma variável estática global:
Substitua a variável pelo seguinte:
fonte
A coisa mais próxima em JavaScript de uma variável estática é uma variável global - isso é simplesmente uma variável declarada fora do escopo de uma função ou literal de objeto:
A outra coisa que você poderia fazer seria armazenar variáveis globais dentro de um objeto literal como este:
E, em seguida, acessar o variabels assim:
foo.bar
.fonte
Para condensar todos os conceitos de classe aqui, teste isto:
Bem, outra maneira de examinar as melhores práticas nessas coisas é ver como o coffeescript traduz esses conceitos.
fonte
No JavaScript, as variáveis são estáticas por padrão. Exemplo :
O valor de x é incrementado em 1 a cada 1000 milissegundos.
Ele imprimirá 1,2,3, etc.
fonte
Existe outra abordagem, que resolveu meus requisitos depois de navegar neste tópico. Depende exatamente do que você deseja obter com uma "variável estática".
A propriedade global sessionStorage ou localStorage permite que os dados sejam armazenados durante toda a vida útil da sessão ou por um período indefinido por mais tempo, até que sejam explicitamente limpos, respectivamente. Isso permite que os dados sejam compartilhados entre todas as janelas, quadros, painéis de guias, pop-ups, etc. da sua página / aplicativo e é muito mais poderoso do que uma simples "variável estática / global" em um segmento de código.
Evita todos os problemas com o escopo, o tempo de vida, a semântica, a dinâmica etc. das variáveis globais de nível superior, como Window.myglobal. Não sabe o quão eficiente é, mas isso não é importante para quantidades modestas de dados, acessadas a taxas modestas.
Facilmente acessado como "sessionStorage.mydata = qualquer coisa" e recuperado da mesma forma. Consulte "JavaScript: O Guia Definitivo, Sexta Edição", David Flanagan, ISBN: 978-0-596-80552-4, Capítulo 20, seção 20.1. É possível fazer o download deste PDF facilmente por simples pesquisa ou na sua assinatura O'Reilly Safaribooks (vale o peso em ouro).
fonte
As funções / classes permitem apenas um construtor para o escopo do objeto.
Function Hoisting, declarations & expressions
Fechamentos - as cópias do fechamento funcionam com dados preservados.
Classes de função ES5 : usa Object.defineProperty (O, P, Attributes)
Criou alguns métodos usando `` , para que, de uma só vez, possa entender as classes de função facilmente.
Abaixo, o snippet de código é testar sobre cada instância tem sua própria cópia dos membros da instância e membros estáticos comuns.
Classes ES6: as classes ES2015 são um açúcar simples sobre o padrão OO baseado em protótipo. Ter um único formulário declarativo conveniente facilita o uso de padrões de classe e incentiva a interoperabilidade. As classes suportam herança baseada em protótipo, super chamadas, instância e métodos estáticos e construtores.
Exemplo : consulte meu post anterior.
fonte
Existem 4 maneiras de emular variáveis estáticas de função local em Javascript.
Método 1: Usando propriedades do objeto de função (suportadas em navegadores antigos)
Método 2: usando um fechamento, variante 1 (suportada em navegadores antigos)
Método 3: usando um fechamento, variante 2 (também suportada em navegadores antigos)
Método 4: usando um fechamento, variante 3 (requer suporte para EcmaScript 2015)
fonte
Você pode definir funções estáticas no JavaScript usando a
static
palavra-chave:No momento da redação deste texto, você ainda não pode definir propriedades estáticas (exceto funções) dentro da classe. As propriedades estáticas ainda são uma proposta do Estágio 3 , o que significa que ainda não fazem parte do JavaScript. No entanto, não há nada que o impeça de simplesmente atribuir a uma classe como você faria com qualquer outro objeto:
Nota final: tenha cuidado ao usar objetos estáticos com herança - todas as classes herdadas compartilham a mesma cópia do objeto .
fonte
No JavaScript, não há termo ou palavra-chave estática, mas podemos colocar esses dados diretamente no objeto de função (como em qualquer outro objeto).
fonte
Eu uso muito variáveis de função estática e é uma pena que o JS não tenha um mecanismo interno para isso. Muitas vezes vejo código em que variáveis e funções são definidas em um escopo externo, mesmo que sejam usadas apenas dentro de uma função. Isso é feio, propenso a erros e apenas pede problemas ...
Eu vim com o seguinte método:
Isso adiciona um método 'estático' a todas as funções (sim, apenas relaxe), quando chamado, adiciona um objeto vazio (_statics) ao objeto de função e o retorna. Se uma função init for fornecida, _statics será definido como resultado init ().
Você pode então fazer:
Comparando isso com um IIFE que é a outra resposta correta, isso tem a desvantagem de adicionar uma atribuição e uma se a cada chamada de função e adicionar um membro '_statics' à função, no entanto, existem algumas vantagens: os argumentos estão disponíveis em a parte superior que não está na função interna, o uso de 'estático' no código da função interna é explícito com um '_s'. prefixo, e é geralmente mais simples olhar e entender.
fonte
Resumo:
No
ES6
/ ES 2015, aclass
palavra - chave foi introduzida com umastatic
palavra-chave acompanhada . Lembre-se de que este é o açúcar sintático do modelo de herança prototípica que o javavscript incorpora. Astatic
palavra-chave funciona da seguinte maneira para métodos:fonte
Eu usei o protótipo e assim funcionou:
ou usando um getter estático:
fonte
As variáveis no nível da janela são como estáticas no sentido de que você pode usar referência direta e elas estão disponíveis para todas as partes do seu aplicativo
fonte
Não existe uma variável estática no Javascript. Essa linguagem é orientada a objetos com base em protótipos, portanto, não há classes, mas protótipos de onde os objetos se "copiam".
Você pode simulá-los com variáveis globais ou com prototipagem (adicionando uma propriedade ao protótipo):
fonte
Function.prototype
function circle() {}
|circle.prototype
|circle.prototype.pi = 3.14
|circle.prototype
|Function.prototype
|Function.__proto__
(se é isso que você quis dizer)Trabalhando com sites MVC que usam jQuery, gosto de garantir que as ações do AJAX em determinados manipuladores de eventos só possam ser executadas quando a solicitação anterior for concluída. Eu uso uma variável de objeto jqXHR "estática" para conseguir isso.
Dado o seguinte botão:
Eu geralmente uso um IIFE como este para meu manipulador de cliques:
fonte
Se você quiser usar o protótipo, existe uma maneira
Fazendo isso, você poderá acessar a variável do contador a partir de qualquer instância e qualquer alteração na propriedade será refletida imediatamente !!
fonte