Const em JavaScript: quando usá-lo e é necessário?

349

Recentemente, encontrei a constpalavra - chave em JavaScript. Pelo que sei, ele é usado para criar variáveis ​​imutáveis e testei para garantir que não possa ser redefinido (no Node.js.):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

Percebo que ele ainda não está padronizado em todos os navegadores - mas estou interessado apenas no contexto do Node.js.8 e observei que certos desenvolvedores / projetos parecem favorecer bastante quando a varpalavra - chave pode ser usada para o mesmo efeito.

Então, minhas perguntas são:

  • Quando é apropriado usar constno lugar de var?
  • Deve ser usado toda vez que uma variável que não será redesignada for declarada?
  • Realmente faz alguma diferença se varé usado no lugar constou vice-versa?
axdg
fonte
11
Isso ainda não parece padronizado (talvez no EC6?). Você encontrará informações adicionais sobre isso aqui: developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Sebastien C.
11
Const tem um desempenho ruim, porém jsperf.com/const-vs-var-mod-3 #
Deepu

Respostas:

462

Existem dois aspectos em suas perguntas: quais são os aspectos técnicos do uso em constvez de vare quais são os aspectos relacionados ao ser humano.

A diferença técnica é significativa. Em linguagens compiladas, uma constante será substituída no momento da compilação e seu uso permitirá outras otimizações, como a remoção do código morto, para aumentar ainda mais a eficiência do código em tempo de execução. Os mecanismos JavaScript recentes (termo pouco usado) compilam o código JS para obter melhor desempenho, portanto, o uso da palavra-chave const os informaria que as otimizações descritas acima são possíveis e devem ser feitas. Isso resulta em melhor desempenho.

O aspecto relacionado ao ser humano é sobre a semântica da palavra-chave. Uma variável é uma estrutura de dados que contém informações que se espera que sejam alteradas. Uma constante é uma estrutura de dados que contém informações que nunca serão alteradas. Se houver espaço para erro, varsempre deve ser usado. No entanto, nem todas as informações que nunca mudam na vida útil de um programa precisam ser declaradas const. Se, em diferentes circunstâncias, as informações mudarem, use varpara indicar isso, mesmo que a alteração real não apareça no seu código.

Tibos
fonte
4
Saúde, presumi que o Mozilla / Google não teria adicionado suporte constante aos mecanismos JS sem motivo. Vou me certificar de usar const, quando aplicável.
axdg
6
constobjetos parecem mutáveis, então não tenho certeza de quão rigoroso o compilador JS realmente é. Talvez o modo "use strict" faça a diferença também.
quer
9
@ Rudie O recurso que você está procurando é chamado de congelamento do objeto. constapenas impede a reatribuição da "variável" para outro valor. const a = {}; a = {};irá lançar um erro no modo estrito.
Tibos 28/11
Uso const em geral, em vez de deixar para a maioria das variáveis, assim como em Java adiciono final à maioria das declarações de variáveis.
codificação
2
If there is room for error, var should always be used. Hoje isso não se aplica mais, com ferramentas como ESLint apontando imediatamente para a constviolação.
Vitaly-t
72

Atualização de 2017

Essa resposta ainda recebe muita atenção. Vale a pena notar que esta resposta foi postada no início de 2014 e muita coisa mudou desde então.suporte agora é a norma. Todos os navegadores modernos agora suportam, constpor isso deve ser bastante seguro de usar sem problemas.


Resposta original de 2014

Apesar de ter um suporte de navegador bastante decente , evitaria usá-lo por enquanto. Do artigo da MDN emconst :

A implementação atual do const é uma extensão específica da Mozilla e não faz parte do ECMAScript 5. É suportada no Firefox & Chrome (V8). No Safari 5.1.7 e Opera 12.00, se você definir uma variável com const nesses navegadores, ainda poderá alterar seu valor posteriormente. Ele não é suportado no Internet Explorer 6-10, mas está incluído no Internet Explorer 11. A palavra-chave const atualmente declara a constante no escopo da função (como variáveis ​​declaradas com var).

Em seguida, continua dizendo:

constserá definido pelo ECMAScript 6, mas com semânticas diferentes. Semelhante às variáveis ​​declaradas com a instrução let, as constantes declaradas com const terão o escopo do bloco.

Se você usar, constprecisará adicionar uma solução alternativa para oferecer suporte a navegadores um pouco mais antigos.

James Donnelly
fonte
6
Ótima resposta - embora eu já tenha lido o artigo sobre MDN. Como eu disse, eu estava mais interessado em saber se o V8 trataria especificamente a const de maneira diferente da var. Acho que o @Tibos esclareceu isso.
axdg
James, obrigado por apontar o aspecto do suporte. imho todas as respostas javascript devem incluir uma falha no suporte do navegador. bem explicado
hubson bropa
4
Nota O ES6 recebeu um congelamento de recursos em agosto de 2014. Em julho de 2015, o padrão foi oficialmente lançado. Se você está lendo isso agora, significa que deve seguir a resposta aceita, conforme descrito, se o seu código for gerenciado por um mecanismo atualizado.
Filip Dupanović
A questão OP é específico node.js
Nicu Surdu
@NicolaeSurdu sure. É também a partir de Janeiro de 2014, por isso é, provavelmente, principalmente redundante agora em 2017.
James Donnelly
41

Por que usar const, a resposta do @ Tibos é ótima.

Mas você disse:

Pelo que sei, é usado para criar variáveis ​​imutáveis

Isso está errado . Mutar uma variável é diferente de reatribuir:

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning

Com const, você não pode fazer isso:

const hello = 'world'
hello = 'bonjour!' // error

Mas você pode alterar sua variável:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

Portanto, qualquer processo que altere o valor da variável sem usar o =sinal está modificando a variável.

Nota: +=por exemplo é ... redesignando!

var a = 5
a += 2 // is the same as a = a + 2

Portanto, a linha inferior é: constnão impede que você mude variáveis, impede que você as atribua novamente.

math2001
fonte
4
sua declaração "qualquer processo que altere o valor da variável sem usar o =sinal está desativado" está tecnicamente errado. Por exemplo, const marks=[92,83]; marks[2]=95; console.log(marks)será exibido [92, 83, 95]. marksfoi mutado, via sinal de igual.
Churvey #
5
"Mas você disse: << Pelo que sei, é usado para criar variáveis ​​imutáveis ​​>> Isso está errado . Mutar uma variável é diferente de reatribuir" Não, não é. A reatribuição está mudando a variável. Você está falando sobre a mutação do objeto ao qual a referência na variável se refere. Isso é uma coisa completamente diferente.
TJ Crowder
Cheguei aqui porque estou tentando entender constno contexto de matrizes (semelhante ao exemplo @chharvey usado). No caso de const countArray = countup(n - 1); countArray.push(n);o consté re-atribuído a cada vez. Então, por que usar conste não var?
YCode 20/03
11
@YCode no. quando você usa const countArray, nunca será reatribuído. Você ainda pode enviar para a matriz, que altera seus membros e comprimento, mas não chamamos isso de reatribuição. você usa em constvez de letou varquando deseja impedir a reatribuição. BTW, se você não quer permitir a reatribuição, leté quase sempre melhor do que var.
chharvey 20/03
@chharvey Obrigado! Sua resposta me levou a "passar por valor versus passar por referência", um novo conceito e um estranho - onde a modificação do valor é a reatribuição. Qualquer pessoa que precise de mais explicações deve verificar as respostas aqui: stackoverflow.com/q/46131828/5965865
YCode 22/03
38

Para integrar as respostas anteriores, há uma vantagem óbvia em declarar variáveis ​​constantes, além do motivo do desempenho: se você tentar alterá-las ou declará-las acidentalmente no código, o programa não alterará o valor ou emitirá um erro.

Por exemplo, compare:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}

com:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}

ou

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0

com

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0
janesconference
fonte
Você deve dizer que esse comportamento "imutável" é aplicável apenas a Strings, Basic Types. Utilizando Objetos, Matrizes etc., é possível alterar os valores, mas não é possível atribuir novamente um novo "Objeto", por exemplo, const a = ["a", "b"]; a = []; lançará um erro, caso contrário, é possível #
Fer To
Você deve ter um exemplo em que tenta alterar também o valor de uma constante.
Joshua Pinter
Usando const é muito parecido com modificadores de acesso, a verdadeira imutabilidade não é o objetivo.
precisa saber é o seguinte
32

constnão é imutável.

Do MDN :

A declaração const cria uma referência somente leitura para um valor. Isso não significa que o valor que ele possui é imutável, apenas que o identificador da variável não pode ser reatribuído.

Anthony
fonte
24
Isso é um pouco enganador. Para números, strings, booleanos etc. (primitivos) consté imutável. Para objetos e matrizes, não é possível reatribuir, mas o conteúdo pode ser alterado (por exemplo, array.push).
Florian Wendelborn
2
As primitivas JS são sempre imutáveis. Se você usa constou não, isso não afeta isso.
12Me21
11
@Dodekeract, portanto, não é imutável por definição. Se os valores podem mudar não é imutável, embora ele funciona como imutável para os primitivos que você listou
Anthony
13

var : declara uma variável, a inicialização de valor opcional.

let : Declara uma variável local com escopo de bloco.

const : declara uma constante nomeada somente leitura.

Ex:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.
Srikrushna
fonte
10

Você tem ótimas respostas, mas vamos simplificar.

const deve ser usado quando você tiver uma constante definida (leia-se: ela não será alterada durante a execução do programa).

Por exemplo:

const pi = 3.1415926535

Se você acha que isso pode ser alterado em execução posterior, use a var.

A diferença prática, baseada no exemplo, é que com constvocê sempre presumirá que pi será 3,14 [...], é um fato.

Se você o definir como a var, pode ser 3,14 [...] ou não.

Para uma resposta mais técnica, o @Tibos está academicamente certo.

Edgar Griñant
fonte
7

Na minha experiência, uso const quando quero definir algo que talvez queira alterar mais tarde, sem precisar procurar o código procurando por bits que foram codificados permanentemente, por exemplo, um caminho de arquivo ou nome de servidor.

O erro no seu teste é outra coisa, você está tentando criar outra variável chamada x; esse seria um teste mais preciso.

const x = 'const';
x = 'not-const';
Funkotron_King
fonte
9
Entendi o que você quer dizer, mas - é engraçado que "constante" para você signifique "coisa que eu possa querer mudar". : P
Venryx
4

Preferência pessoal realmente. Você pode usar const quando, como diz, não será reatribuído e é constante. Por exemplo, se você deseja atribuir seu aniversário. Seu aniversário nunca muda, então você pode usá-lo como uma constante. Mas sua idade muda, então isso pode ser uma variável.

Carl Markham
fonte
17
Isso seria um script muito demorado!
nullability
3
@ anulabilidade Depende de quantas pessoas você está acompanhando. Mais de algumas dezenas e o script não precisará ser executado por muito tempo :).
Millie Smith
4

Resumo:

const cria uma ligação imutável, o que significa que o identificador de variável const não é redesignável.

const a = "value1";

você não pode reatribuí-lo com

a = "value2";

No entanto, se o identificador const possuir um objeto ou uma matriz, o valor dele poderá ser alterado na medida em que não o estivermos redesignando.

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

Observe que const é um escopo de bloco, assim como let, que não é o mesmo que var (que é de escopo de função)

Em resumo, quando algo provavelmente não mudar através da realocação, use const ou use let ou var, dependendo do escopo que você gostaria de ter.

É muito mais fácil raciocinar sobre o código quando está óbvio o que pode ser alterado através da nova atribuição e o que não pode ser. Mudar uma const para uma let é muito simples. E ficar const por padrão faz você pensar duas vezes antes de fazê-lo. E isso é, em muitos casos, uma coisa boa.

Tejas Patel
fonte
2
Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var': no ​​momento da codificação, quando falamos sobre código-padrão, geralmente usamos o nome do identificador, que é fácil de entender por outro usuário / desenvolvedor. Por exemplo, se estamos trabalhando, pensamos em muitas funções nas quais usamos alguma entrada e processamos isso e retornamos algum resultado, como:

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

Nos exemplos acima, ambas as funções produzem resultados diferentes-2, mas usam o mesmo nome de variáveis. Aqui podemos ver 'processo' e 'resultado', ambos são usados ​​como variáveis ​​e deveriam ser.

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

Antes de usar 'let' no java-script, precisamos adicionar 'use strict' na parte superior do arquivo js

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

No exemplo acima, você pode rastrear qual função é executada quando e qual função não é usada durante uma ação específica.

vinod
fonte
1

Primeiro, três coisas úteis sobre const(além das melhorias de escopo com as quais compartilha let):

  • Ele documenta para as pessoas que leem o código posteriormente que o valor não deve ser alterado.
  • Isso impede que você (ou qualquer pessoa que esteja atrás de você) altere o valor, a menos que retorne e altere a declaração intencionalmente.
  • Isso pode salvar o mecanismo JavaScript de algumas análises em termos de otimização. Por exemplo, você declarou que o valor não pode mudar; portanto, o mecanismo não precisa trabalhar para descobrir se o valor muda, para que possa decidir se otimizar com base no valor que não muda.

Suas perguntas:

Quando é apropriado usar constno lugar de var?

Você pode fazer isso sempre que declarar uma variável cujo valor nunca muda. Se você considera apropriado é inteiramente da sua preferência / da sua equipe.

Deve ser usado toda vez que uma variável que não será redesignada for declarada?

Isso depende de você / sua equipe.

Realmente faz alguma diferença se var is used in place ofconst` ou vice-versa?

Sim:

  • vare consttem regras de escopo diferentes. (Você pode querer comparar com lete não var.) Especificamente: conste lettêm escopo de bloco e, quando usados ​​no escopo global, não criam propriedades no objeto global (mesmo que criem globais). varpossui escopo global (quando usado no escopo global) ou escopo de função (mesmo se usado em um bloco) e, quando usado no escopo global, cria uma propriedade no objeto global.
  • Veja minhas "três coisas úteis" acima, todas elas se aplicam a essa pergunta.
TJ Crowder
fonte
1

A semântica varelet

vare letsão uma declaração para a máquina e para outros programadores:

Pretendo que o valor dessa atribuição mude ao longo da execução. Não confie no valor eventual desta tarefa.

Implicações do uso varelet

vare letforçar outros programadores a lerem todo o código intermediário da declaração para o uso eventual e raciocinarem sobre o valor da atribuição naquele ponto na execução do programa.

Eles enfraquecem o raciocínio da máquina para que o ESLint e outros serviços de linguagem detectem corretamente nomes de variáveis ​​digitados incorretamente em atribuições posteriores e reutilizam o escopo de nomes de variáveis ​​de escopo externo onde o escopo interno esquece de declarar.

Eles também fazem com que os tempos de execução executem muitas iterações em todos os caminhos de código para detectar se são realmente constantes, antes que possam otimizá-los. Embora isso seja menos problemático do que a detecção de erros e a compreensibilidade do desenvolvedor.

Quando usar const

Se o valor da referência não for alterado ao longo da execução, a sintaxe correta para expressar a intenção do programador é const. Para objetos, alterar o valor da referência significa apontar para outro objeto, pois a referência é imutável, mas o objeto não é.

constobjetos " "

Para referências a objetos, o ponteiro não pode ser alterado para outro objeto, mas o objeto criado e atribuído a uma constdeclaração é mutável. Você pode adicionar ou remover itens de uma constmatriz referenciada e alterar chaves de propriedade em um constobjeto referenciado.

Para alcançar objetos imutáveis ​​(que, novamente, facilitam o raciocínio de seu código para humanos e máquinas), você pode Object.freezeo objeto em declaração / atribuição / criação, como este:

const Options = Object.freeze(['YES', 'NO'])

O Object.freeze afeta o desempenho, mas seu código provavelmente está lento por outros motivos. Você deseja criar um perfil.

Você também pode encapsular o objeto mutável em uma máquina de estado e retornar cópias profundas como valores (é assim que o estado Redux e React funcionam). Consulte Evitando o estado global mutável no JS do navegador para obter um exemplo de como construir isso a partir dos primeiros princípios.

Quando vare leté uma boa combinação

lete varrepresentam estado mutável. Eles devem, na minha opinião, ser usados ​​apenas para modelar o estado mutável real . Coisas como " a conexão está viva? ".

Elas são melhor encapsuladas em máquinas de estado testáveis ​​que expõem valores constantes que representam " o estado atual da conexão ", que é uma constante a qualquer momento e em que o restante do seu código está realmente interessado.

A programação já é bastante difícil com a composição de efeitos colaterais e a transformação de dados. Transformar todas as funções em uma máquina de estados não testável, criando um estado mutável com variáveis ​​apenas aumenta a complexidade.

Para uma explicação mais sutil, consulte Shun the Mutant - The case forconst .

Josh Wulf
fonte
0

Não sou especialista no negócio de compilação JS, mas faz sentido dizer que a v8 faz uso da flag const

Normalmente, depois de declarar e alterar um monte de variáveis, a memória fica fragmentada e a v8 pára para executar, faz uma pausa por alguns segundos, para fazer gc ou coleta de lixo.

se uma variável for declarada com const v8, pode-se confiar em colocá-la em um contêiner de tamanho fixo apertado entre outras variáveis ​​const, pois nunca será alterada. Também pode salvar as operações adequadas para esses tipos de dados, pois o tipo não será alterado.

judeu
fonte
0

Quando se trata da decisão entre let e const , sempre prefira const para que o uso seja claro no código. Dessa forma, se você tentar redeclarar a variável, receberá um erro. Se não houver outra opção além de redeclará-la, basta alternar para deixar . Observe que, como Anthony diz, os valores não são imutáveis ​​(por exemplo, um objeto const pode ter propriedades alteradas).

Quando se trata de var , como o ES6 foi lançado, nunca o usei no código de produção e não consigo pensar em um caso de uso para ele. No entanto, cuidado com o fato de que variáveis ​​declaradas com var não possuem escopo de bloco.

Tiago Martins Peres
fonte