Gabe Brasil

Var no JavaScript: o que é e como funciona

Var no JavaScript: o que é e como funciona

A utilização de var foi, por muito tempo, a forma tradicional de declarar variáveis em JavaScript, até a chegada de let e const na versão ES6 (ECMAScript 2015). Embora ainda funcione, var possui comportamentos específicos — como escopo de função e hoisting — que podem gerar confusão e provocar problemas sutis no código.

Neste artigo, vamos entender como var funciona, por que ela pode ser problemática e por que seu uso caiu em desuso nos projetos modernos.

Escopos

A variável declarada com var pode pertencer ao escopo global ou ao escopo de função, mas não ao escopo de bloco (como em if, for, ou while).

Escopo GlobalEscopo de FunçãoEscopo de Bloco
✔️✔️

Escopo Global

Sempre que uma variável é declarada com var fora de uma função, ela pertence ao escopo global. Isso significa que pode ser acessada em qualquer parte do código, inclusive dentro de funções e blocos como if, while, try/catch, entre outros.

var foo = "Foo"; // Escopo global

function test() {
  console.log(foo); // Foo
}

test();

if (true) {
  console.log(foo); // Foo
}

console.log(foo); // Foo

Neste exemplo, a variável foo foi declarada fora de qualquer função, portanto pertence ao escopo global. Dessa forma, ela pode ser acessada de qualquer parte do código, incluindo funções e blocos como if, while ou try/catch.

Escopo de Função

Sempre que uma variável for declarada com var dentro de uma função, ela pertence ao escopo de função. Isso significa que ela só pode ser acessada dentro da própria função onde foi declarada.

function test() {
  var foo = true; // Escopo de função
  
  console.log(foo); // true
}

test();

function test2() {
  console.log(foo); // Uncaught ReferenceError: foo is not defined
}

test2();

console.log(foo); // Uncaught ReferenceError: foo is not defined

No exemplo acima, a variável foo é declarada dentro da função test. Quando tentamos acessar foo fora do escopo dessa função, seja em outra função ou no escopo global, recebemos um erro indicando que a variável não está definida. Isso acontece porque foo existe apenas dentro do escopo da função em que foi declarada.

Escopo de Bloco

Variáveis declaradas com var não têm escopo de bloco.

Quando uma variável é declarada dentro de um bloco (como if, for ou outros), mas fora de uma função, ela pertence ao escopo global. Se estiver dentro de uma função, ela terá o escopo de função, mesmo que esteja dentro de um bloco.

var foo = "Foo"; // Escopo global

if (true) {
  var bar = "Bar"; // Também possui escopo global
}

function test() {
  var thul = "Thul"; // Escopo de função

  if (true) {
    var vex = "Vex"; // Também possui escopo de função
  }
}

test();

No exemplo acima, tanto a variável bar quanto a variável vex foram declaradas dentro de blocos if. A diferença é que bar está fora de qualquer função, portanto pertence ao escopo global, enquanto vex está dentro da função test, o que faz com que ela pertença ao escopo de função.

Atribuição Opcional

A atribuição de valor a uma variável declarada com var é opcional. Ou seja, você pode declarar uma var sem atribuir um valor inicial. Quando isso acontece, o JavaScript automaticamente define o valor inicial como undefined.

var foo;

console.log(foo); // undefined

foo = true;

console.log(foo); // true

No exemplo acima, a variável foo é declarada sem um valor inicial, por isso seu valor padrão é undefined, como mostrado no primeiro console.log. Em seguida, atribuímos o valor booleano true a ela, que é exibido corretamente no segundo console.log.

Reatribuição

Variáveis declaradas com var podem ser reatribuídas a qualquer momento, ou seja, você pode alterar o valor da variável após sua declaração inicial.

var foo = true;

console.log(foo); // true

foo = false;

console.log(foo); // false

No exemplo acima, o primeiro console.log exibe o valor inicial da variável foo, que é true. Em seguida, após a reatribuição para false, o segundo console.log exibe o novo valor.

Redeclaração

Uma peculiaridade do var que pode causar problemas se não for usada com cuidado é que ela pode ser redeclarada — ou seja, você pode declarar a mesma variável novamente no mesmo escopo.

var user = "Jane";

console.log(user); // Jane

if (user.length <= 10) {
  var user = 10;

  console.log("Username: less than " + user + " chars."); // Username: less than 10 chars.
}

console.log("Username length: " + user.length); // Username length: undefined

No exemplo acima, a variável user é inicialmente um texto com o valor "Jane". Em seguida, o código verifica se o comprimento desse texto (user.length) é menor ou igual a 10.

Como essa condição é verdadeira, o bloco if é executado, onde ocorre uma redeclaração da variável user, atribuindo a ela o valor 10, que é um número.

Como a variável user foi declarada com var no escopo global, essa nova declaração sobrescreve a anterior.

Isso gera um problema na última linha do código, que tenta acessar a propriedade .length da variável user. Como user agora é um número, e números não possuem a propriedade .length, o resultado é undefined.

Resumindo o que ocorre na última linha:

  • .length é uma propriedade que retorna o tamanho de um texto;
  • user foi originalmente um texto, mas depois passou a ser um número;
  • Por isso, user.length não funciona e retorna undefined.

Declarações múltiplas

Você pode declarar e atribuir valores a múltiplas variáveis usando apenas uma única instrução var. Isso não significa que todos esses valores estejam armazenados em uma única variável, mas sim que é uma forma prática de omitir várias declarações e criar tudo em uma linha só.

var foo = "Foo", bar = "Bar";

console.log(foo); // Foo

console.log(bar); // Bar

Agora, veja o mesmo código usando declarações individuais para cada variável:

var foo = "Foo";

var bar = "Bar";

console.log(foo); // Foo

console.log(bar); // Bar

Hoisting

Quando uma variável é declarada com var, o hoisting faz com que sua declaração seja “elevada” para o início do escopo onde foi declarada.

Veja este exemplo no escopo global:

var foo = true;

console.log(foo); // true

var bar = false;

console.log(bar); // false

Agora, veja uma representação conceitual do que acontece por trás dos panos:

var foo; // Declaração elevada pelo hoisting
var bar; // Declaração elevada pelo hoisting

foo = true;

console.log(foo); // true

bar = false;

console.log(bar); // false

Observe que apenas as declarações são elevadas. Suas inicializações permanecem no mesmo lugar.

Como só a declaração é movida para o topo, a variável recebe automaticamente o valor undefined até ser inicializada. Isso significa que é possível acessar uma variável antes da sua declaração sem que isso gere erro — porém, seu valor será undefined.

console.log(foo); // undefined

var foo = "Foo";

console.log(foo); // Foo

Na representação conceitual desse código, temos:

var foo; // Declaração elevada pelo hoisting

console.log(foo); // undefined

foo = "Foo";

console.log(foo); // Foo

Como a declaração da variável foo foi elevada pelo hoisting e o JavaScript inicializa automaticamente a variável com undefined, no primeiro console aparece undefined em vez de um erro.

Pertencimento ao Objeto Global window

No ambiente do navegador, o window é o objeto global que representa a janela (ou aba) do navegador onde a página está sendo exibida. Ele contém todas as variáveis globais, funções, objetos do DOM, métodos nativos e muito mais. O JavaScript pode acessar e até modificar esse objeto durante a execução do script, mas essas alterações nunca são permanentes, já que apenas o navegador tem controle total sobre ele.

Em alguns casos, variáveis declaradas com var podem ser adicionadas ao objeto window. Mas isso depende do tipo de script em que a variável foi declarada.

  • Arquivo tradicional: <script src=""></script>
  • Arquivo do tipo módulo: <script src="" type="module"></script>

Com script tradicional

Quando uma variável é declarada com var em um arquivo tradicional, ela é automaticamente adicionada ao objeto global window.

var userName = "Jane";

console.log(window.userName); // Jane
<script src=”main.js”></script>

Neste exemplo, a variável userName foi declarada em um script tradicional. Ao acessarmos window.userName, vemos que a variável foi, de fato, adicionada ao objeto global window.

Conflitos com variáveis globais do objeto window

Como vimos no início desta seção sobre o objeto global window, ele possui diversas propriedades úteis relacionadas à janela do navegador. Por exemplo, podemos consultar a largura atual da janela com:

console.log(window.innerWidth); // Valor atual da largura da janela do seu navegador

Suponha que a largura atual da janela seja 1920 pixels. É importante saber que o valor retornado por window.innerWidth é do tipo número, ou seja, ele retorna apenas o valor 1920.

Agora, imagine que você declare uma variável com var usando o mesmo nome innerWidth em um arquivo JavaScript tradicional:

var innerWidth = "600px";

console.log(window.innerWidth); // 600px

Observe que a variável innerWidth possui um texto como valor “600px”. Como estamos em um arquivo tradicional, toda var será adicionada ao objeto global.

console.log(window.innerWidth); // Valor atual da largura da janela do seu navegador

var innerWidth = "600px";

console.log(window.innerWidth); // 600px

Note que a variável innerWidth foi declarada com o valor “600px” que é um texto. Como estamos em um arquivo tradicional, toda variável declarada com var no escopo global será adicionada ao objeto global window.

Assim, ao acessar window.innerWidth, você não obterá mais a largura atual da janela como número, mas sim o valor da sua variável (“600px“).

Isso pode gerar diversos problemas, pois:

  • Não podemos mais confiar que window.innerWidth retornará um número representando a largura da janela;
  • Perdemos a referência ao valor atualizado da largura da janela do navegador.

Por isso, é fundamental ter cuidado para não sobrescrever nenhuma variável ou propriedade importante do objeto global window.

Com script do tipo módulo

Quando a mesma variável é declarada dentro de um arquivo com type="module", o comportamento é diferente:

var userName = "Jane";

console.log(window.userName); // undefined
<script src=”main.js” type=”module”></script>

Aqui, embora o código seja o mesmo, ao tentar acessar window.userName, recebemos undefined. Isso acontece porque variáveis declaradas com var em scripts do tipo módulo não são adicionadas ao objeto global window.

Observação importante

O undefined retornado em window.userName neste caso não tem relação com a inicialização padrão de variáveis var, onde o valor inicial é undefined.

Para esclarecer isso, veja este exemplo:

var userName = "Jane";

console.log(window.color); // undefined

A única variável declarada aqui é userName. Como color nunca foi declarada, o JavaScript retorna undefined ao tentar acessar window.color, indicando que essa propriedade simplesmente não existe no objeto window. Ou seja, o undefined não vem de uma atribuição padrão, mas do fato de que essa variável não foi criada no objeto window.


Conclusão

Embora o var ainda funcione e faça parte da linguagem JavaScript, entender seu comportamento — especialmente em relação a escopo, hoisting e o objeto global window — é essencial para evitar bugs e confusões no código. Com a chegada de let e const, o uso de var se tornou cada vez menos recomendado, mas conhecer suas particularidades é importante, especialmente ao lidar com códigos legados ou manter compatibilidade com projetos antigos.

Espero que este artigo tenha ajudado você a entender de forma clara como o var funciona no JavaScript.

Se você tiver alguma dúvida, sugestão ou quiser conversar mais sobre o assunto, fique à vontade para me chamar no LinkedIn.

Escrito carinhosamente com ❤️☕.