Diferenças entre var, let e const em JavaScript
Ao declarar variáveis, é comum usar var
, pois é o método normalmente conhecido. No entanto, desde o ECMAScript 6, duas novas palavras-chave foram introduzidas no JavaScript para declarar variáveis, que são let
e const
. Para entender a necessidade delas, vamos primeiro olhar alguns pontos sobre como o var
funciona.
Variáveis declaradas com var
são adicionadas ao início do código em tempo de execução, então elas são variáveis globais.
Por exemplo, temos esta função com uma variável declarada dentro:
function myFunction(number, compare) {
var status;
if (number < compare) {
status = 'O número é menor';
} else if (number > compare) {
status = 'O número é maior';
} else {
status = 'O número é igual';
}
return status;
}
myFunction(1, 2); // O número é menor
O que realmente acontece é o seguinte:
var status; // 'status' é globalizado
function myFunction(number, compare) {
if (number < compare) {
status = 'O número é menor';
} else if (number > compare) {
status = 'O número é maior';
} else {
status = 'O número é igual';
}
return status;
}
myFunction(1, 2); // O número é menor
// então, se usarmos a variável status fora da função, ela existiria, apenas indefinida
console.log(status); // undefined
Mesmo isso funcionaria sem problemas (embora seja uma má prática):
function myFunction(number, compare) {
if (number < compare) {
status = 'O número é menor';
} else if (number > compare) {
status = 'O número é maior';
} else {
status = 'O número é igual';
}
var status; // não faça isso
return status;
}
myFunction(1, 2); // O número é menor
Esse comportamento é chamado de hoisting, e acontece querendo ou não.
No entanto, let
e const
não funcionam assim. Ao contrário de var
, eles funcionam no nível do bloco de código e não são transformados em variáveis globais em tempo de execução. Isso nos permite ter mais controle sobre como e onde declaramos variáveis e em quais lugares elas podem ser manipuladas.
A palavra-chave const
, como o nome diz, difere de let
porque seus valores não podem ser modificados depois de inicializados, então ela deve ser inicializada com um valor. Isso é bom porque nunca teremos variáveis constantes indefinidas.
Usando o mesmo exemplo com let
:
function myFunction(number, compare) {
let status;
if (number < compare) {
status = 'O número é menor';
} else if (number > compare) {
status = 'O número é maior';
} else {
status = 'O número é igual';
}
return status;
}
myFunction(1, 2); // O número é menor
// nesse caso, a variável status não existe fora da função 'myFunction'
// então lançaria um erro
console.log(status); // ReferenceError: status is not defined
Agora o mesmo exemplo com const
:
function myFunction(number, compare) {
const status
if (number < compare) {
status = 'O número é menor' // TypeError: Assignment to constant variable.
} else if (number > compare) {
status = 'O número é maior' // TypeError: Assignment to constant variable.
} else {
status = 'O número é igual' // TypeError: Assignment to constant variable.
}
return status
}
myFunction(1, 2) // TypeError: Assignment to constant variable.
Embora const
nos dê a capacidade de declarar constantes, um ponto a ser observado é que quando o valor da constante é uma referência, ou seja, um objeto
, outro objeto não pode ser reatribuído à constante, mas o que ela já possui pode ser modificado. Isso ocorre porque a referência ao objeto é mantida, mesmo que suas propriedades sejam modificadas.
Exemplo:
// válido
const person = {
name: '',
surname: '',
age: '',
};
const car = {
wheels: '',
color: '',
doors: '',
};
// não lança erro, porque a referência a 'person' não está sendo modificada
person.name = 'Carlos';
// TypeError: Assignment to constant variable
// Erro, porque está tentando mudar a referência do objeto 'person' para a do objeto 'car'
person = car;
Por essas razões, é altamente recomendado usar let
em vez de var
. Também ao declarar constantes, use const
. Dessa forma, evitamos más práticas e ganhamos mais controle sobre como nossa aplicação funciona.