Qual é o objetivo da palavra-chave var e quando devo usá-la (ou omiti-la)?


1543

NOTA : Esta pergunta foi feita do ponto de vista da versão 3 ou 5. do ECMAScript. As respostas podem ficar desatualizadas com a introdução de novos recursos na versão do ECMAScript 6.

Qual é exatamente a função da varpalavra - chave em JavaScript e qual é a diferença entre

var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;

e

someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;

?

Quando você usaria um deles e por que / o que ele faz?


3
Ao encadear declarações var, colocar uma nova linha após uma vírgula afeta o comportamento? var x = 1, y = 2, [retorno] z = 3;
Alfabravo

4
Não usar "var" também o deixa exposto, caso o nome da variável que você escolheu seja uma variável global definida anteriormente. Veja minha jornada de luto aqui: stackoverflow.com/questions/16704014/...
Scott C Wilson

5
De @Ray Toal meloncard blog (definitivamente uma leitura vale a pena) mudou-se para blog.safeshepherd.com/23/how-one-missing-var-ruined-our-launch
Hefesto

Eu nunca tinha imaginado um poema poderia me inspirar consideração para um problema programático
Félix Gagnon-Grenier

1
@ Gibolt, mas olhe a data da pergunta, é meio que injusto convocar uma pergunta de 2009 para dizer isso. Mesmo assim, ainda é válido como na data atual para manutenção, existem muitos códigos não "modernos" em JS.
Andre Figueiredo

Respostas:


1356

Se você está no escopo global, não há muita diferença. Leia a resposta de Kangax para explicação

Se você estiver em uma função, varcriará uma variável local, "no var" pesquisará a cadeia de escopo até encontrar a variável ou atingir o escopo global (no momento em que a criará):

// These are both globals
var foo = 1;
bar = 2;

function()
{
    var foo = 1; // Local
    bar = 2;     // Global

    // Execute an anonymous function
    (function()
    {
        var wibble = 1; // Local
        foo = 2; // Inherits from scope above (creating a closure)
        moo = 3; // Global
    }())
}

Se você não estiver realizando uma tarefa, precisará usar var:

var x; // Declare x

31
"Realmente não há muita diferença" == "Nenhuma diferença"?
Alex

65
Bem, na verdade sim, há diferença :) Se essa diferença é importante é outra questão. Veja a minha resposta mais abaixo: stackoverflow.com/questions/1470488/...
kangax

4
Eu acho que esse pode ser o argumento de Alex, e é por isso que ele escreveu usando o operador "é igual a"!
James Bedford

18
É como se atirar com uma railgun ... Esquece de colocar um 'var' antes da variável e acaba modificando uma variável em algum lugar da cadeia de escopo ... Tente convencer um Java / C / Python / etc. desenvolvedor que JavaScript vale a pena. Ha! As armadilhas do C / C ++ parecem agradáveis, pelo contrário. Imagine ter que depurar JavaScript ... E algumas pessoas fazem isso, é claro. E há tanta coisa de código (e não simples código, você mente) escrito em JavaScript ...
Albus Dumbledore

6
Se você está no escopo global, não há diferença. >> há uma diferença, que é explicado na resposta abaixo
Max Koretskyi

746

Há uma diferença .

var x = 1 declara variável x no escopo atual (também conhecido como contexto de execução). Se a declaração aparecer em uma função - uma variável local é declarada; se estiver no escopo global - uma variável global é declarada.

x = 1, por outro lado, é apenas uma atribuição de propriedade. Primeiro, ele tenta resolver com xrelação à cadeia de escopo. Se o encontrar em qualquer lugar dessa cadeia de escopo, ele executará a atribuição; se não encontrar x, somente cria xpropriedade em um objeto global (que é um objeto de nível superior em uma cadeia de escopo).

Agora, observe que ela não declara uma variável global, ela cria uma propriedade global.

A diferença entre os dois é sutil e pode ser confusa, a menos que você entenda que as declarações de variáveis ​​também criam propriedades (apenas em um objeto variável) e que todas as propriedades em Javascript (bem, ECMAScript) possuem determinados sinalizadores que descrevem suas propriedades - ReadOnly, DontEnum e Não exclua.

Como a declaração de variável cria propriedade com o sinalizador DontDelete, a diferença entre var x = 1e x = 1(quando executada no escopo global) é que a primeira - declaração de variável - cria a propriedade DontDelete'able, e a segunda não. Como conseqüência, a propriedade criada por meio dessa atribuição implícita pode ser excluída do objeto global e a anterior - a criada por meio da declaração de variável - não pode ser excluída.

Mas isso é apenas teoria, é claro, e na prática há ainda mais diferenças entre os dois , devido a vários erros nas implementações (como as do IE).

Espero que tudo faça sentido :)


[Atualização 16/12/2010]

No ES5 (ECMAScript 5; recentemente padronizado, 5ª edição do idioma), existe o chamado "modo estrito" - um modo de idioma de aceitação, que altera levemente o comportamento de atribuições não declaradas. No modo estrito, a atribuição a um identificador não declarado é um ReferenceError . A lógica para isso era capturar atribuições acidentais, impedindo a criação de propriedades globais indesejadas. Alguns dos navegadores mais recentes já começaram a rolar o suporte ao modo estrito. Veja, por exemplo, minha tabela compat .


Se bem me lembro, acho que uma vez encontrei uma maneira de conseguir deleteuma variável declarada em var com algum evalhack. Se eu me lembrar do truque exato, postarei aqui.
Torre

3
@ Magek Ele pode estar levando sobre variáveis ​​declaradas eval que são deletable. Eu escrevi um post sobre isso uma vez.
kangax

1
Um pouco fora de tópico, mas mencionando-o aqui para referência. "let" é muito semelhante ao "var" e é suportado no Mozilla. A principal diferença é que o âmbito de aplicação de uma variável var é toda a função de envolvente onde como "let" é restrito ao seu bloco
mac

@kangax, e se as duas últimas linhas dos exemplos de Alex fossem misturadas: var someObject = {}e someObject.someProperty = 5? Se somePropertytornaria global, enquanto o objeto de que é propriedade permanece local?
Snapfractalpop #

1
O nome de especificação para o que @kangax chama a DontDelete bandeira é configurável (= false) , você pode ler sobre isso em relação ao Object.definePropertyeObject.getOwnPropertyDescriptor
Paul S.

137

Dizer que é a diferença entre " local e global " não é totalmente preciso.

Talvez seja melhor pensar nisso como a diferença entre " local e mais próximo ". O mais próximo certamente pode ser global, mas nem sempre será esse o caso.

/* global scope */
var local = true;
var global = true;

function outer() {
    /* local scope */
    var local = true;
    var global = false;

    /* nearest scope = outer */
    local = !global;

    function inner() {
        /* nearest scope = outer */
        local = false;
        global = false;

        /* nearest scope = undefined */
        /* defaults to defining a global */
        public = global;
    }
}

3
Não é o escopo mais próximo outeronde você define var global = false;?
precisa saber é o seguinte

@Snekse: 'closest' não se aplica quando <code> var global = false; </code> é declarado. Nessa declaração, 'global' é colocado no escopo de outer () porque 'var' é usado na declaração. Como 'var' não é usado em inner (), ele alterará o valor no próximo nível acima, que é externo ().
Mitch

Gostaria de saber se o seu comentário mudaria se você alterasse essa linha para var global = local;, nesse caso, o escopo local mais próximo seria o escopo externo "local" que está sendo definido ativamente. Embora seja estranho se você alterasse a mesma linha var global = global, nesse caso, o escopo mais próximo ao procurar o valor de globalseria um nível acima no escopo da janela global.
Snekse

80

Quando o Javascript é executado em um navegador, todo o seu código é cercado por uma declaração with, assim:

with (window) {
    //Your code
}

Mais informações sobre with- MDN

Como vardeclara uma variável no escopo atual , não há diferença entre declarar var dentro da janela e nem mesmo declará-la.

A diferença ocorre quando você não está diretamente dentro da janela, por exemplo, dentro de uma função ou dentro de um bloco.

Usar varpermite ocultar variáveis ​​externas com o mesmo nome. Dessa maneira, você pode simular uma variável "privada", mas esse é outro tópico.

Uma regra prática é sempre usar var, porque, caso contrário, você corre o risco de introduzir bugs sutis.

EDIT: Após as críticas que recebi, gostaria de enfatizar o seguinte:

  • vardeclara uma variável no escopo atual
  • O escopo global é window
  • Não usar vardeclarações implícitas varno escopo global (janela)
  • Declarar uma variável no escopo global (janela) usando varé o mesmo que omiti-la.
  • Declarar uma variável em escopos diferentes da janela usando var não é a mesma coisa que declarar uma variável semvar
  • Sempre declare varexplicitamente porque é uma boa prática

1
Não diminuí o voto, mas escopo é provavelmente uma palavra melhor que janela. Sua explicação é um pouco obtusa.
Robert Harvey

4
Eu simplesmente chamo as coisas com seu nome, você quer chamá-lo de "escopo global", tudo bem, mas o lado do cliente, por convenção, é o objeto de janela, esse é o último elemento da cadeia de escopo, é por isso que você pode chamar todos os função e todos os objetos na janela sem escrever "janela".
kentaromiura

2
+1 Esta é uma explicação muito boa - eu nunca ouvi o problema var / no var emoldurado (sem trocadilhos) como este antes.
Doug

A maior parte dessa resposta foi descontinuada letno ES6.
Evan Carroll

3
@EvanCarroll Esta resposta também é tecnicamente incorreta, uma vez que a omissão de var não declara nenhuma variável. Em vez disso, cria uma propriedade que pode ser deletável no objeto global. Além disso, com o modo de "uso estrito" do ES5, a maioria das respostas obviamente não está correta, também não foi ' isso nem foi considerado nesta resposta, pois no momento da pergunta não havia nenhuma referência à versão javascript (adicionada ontem) que implica que o padrão de referência (na época) era o ECMA 262 3rd Edition.
precisa saber é o seguinte

43

Sempre use a varpalavra-chave para declarar variáveis. Por quê? A boa prática de codificação deve ser uma razão suficiente, mas omití-la significa que ela é declarada no escopo global (uma variável como essa é chamada de global "implícita"). Douglas Crockford recomenda nunca usar globals implícitas e de acordo com as Diretrizes de codificação da Apple JavaScript :

Qualquer variável criada sem a var palavra-chave é criada no escopo global e não é coletada como lixo quando a função retorna (porque ela não sai do escopo), apresentando a oportunidade para um vazamento de memória.


17
A "boa prática de codificação" nunca deve ser razão suficiente por si só. Isso equivale a "alguns caras na internet disseram que é assim que meu código deve ficar". Isso é ainda menos válido do que "meu professor disse", a menos que alguém ao menos vagamente entenda a razão por trás da regra.
cHao

@cHao Eu acho que good coding practicesempre é motivo suficiente se for uma prática recomendada, que é e por vários autores de Javascript.
Chris S

8
@ Chris: Não, "boas práticas de codificação" não são razão por si só. A razão pela qual é considerada uma boa prática é o que importa. A menos que esses autores lhe digam por que o recomendam, a recomendação deles não deve ter peso algum. Se você não concordar com os motivos, poderá considerá-lo um mau conselho. E se você segui-lo sem nunca perguntar por que, é assim que o cultismo de carga começa.
cHao

30

Aqui está um bom exemplo de como você pode ser pego por não declarar variáveis ​​locais com var:

<script>
one();

function one()
{
    for (i = 0;i < 10;i++)
    {
        two();
        alert(i);
    }
}

function two()
{
    i = 1;
}
</script>

( ié redefinido a cada iteração do loop, pois não é declarado localmente no forloop, mas globalmente) eventualmente resultando em loop infinito


Caramba! Eu posso imaginar todos os erros que poderiam ser causados ​​por esse erro de digitação.
BonsaiOak 12/10

2
Estou curioso, por que você está passando i como argumento para dois ()? (dentro do loop for) isso é redundante?
kalin

O argumento é ignorado em duas () funções encapsuladas em uma () função, uma vez que a função two () foi definida sem um parâmetro. Você está certo, não é necessário, pois não desempenha nenhum papel.
KK.

Bug ou recurso?
TheMaster

13

Eu diria que é melhor usar varna maioria das situações.

As variáveis ​​locais são sempre mais rápidas que as variáveis ​​no escopo global.

Se você não vardeclarar uma variável, ela estará no escopo global.

Para mais informações, você pode pesquisar "JavaScript da cadeia de escopo" no Google.


Se você declarar uma variável usando a palavra-chave var, ela será criada em tempo de execução; portanto, não deve ser mais lenta? Porque outro é criado no tempo analisado.
Barış Velioğlu

@RyuKaplan - ei, isso é verdade? Eu tentei pesquisar no Google e não consegui nenhuma informação sobre o assunto! Você tem uma autoridade de origem para essa afirmação? Thx
mike roedor

@RyuKaplan A análise / compilação é diferente da execução do código.
219688 Gcampbell

11

Não use var!

varfoi a maneira pré-ES6 de declarar uma variável. Estamos agora no futuro e você deve codificar como tal.

Use constelet

constdeve ser usado em 95% dos casos. Isso faz com que a referência da variável não possa ser alterada, portanto, as propriedades da matriz, objeto e nó do DOM podem ser alteradas e provavelmente deveriam ser const.

letdeve ser usado para qualquer variável que espera ser reatribuída. Isso inclui um loop for. Se você escrever varName =além da inicialização, use let.

Ambos têm escopo no nível do bloco, como esperado na maioria dos outros idiomas.


2
Substitua tudo o que você 'var' por 'const' (substitua tudo). Você notará rapidamente onde estão suas variáveis ​​reatribuídas. Se você tiver muitas delas, provavelmente codificará de maneira não padronizada: a maioria das variáveis ​​transferíveis pode ser incorporada em fechamentos ou como propriedades de objetos. Se você tiver alguns: use 'let' para eles. Por fim, se algumas variáveis ​​não forem delaradas com 'var', elas permanecerão não declaradas e ainda estão presentes no espaço global, cuidado. Sobre o comentário do @Gibolt 'dentro de um loop for', também é recomendável evitar esses loops em "95% dos casos" ;-): os métodos de array são ótimos.
Allez l'OM

Ao dizer que const deve ser usado em 95% dos casos, parece que estamos nos afastando das boas práticas e entrando em dogmas.
Agamemnus

9

outra diferença, por exemplo

var a = a || [] ; // works 

enquanto

a = a || [] ; // a is undefined error.

1
Você poderia explicar por que funciona no caso de variável definida com 'var' e variável não definida com var? A variável é criada antes da avaliação do lado direito da tarefa em caso de var?
Matt

6
@Lucek, porque var aé içado para a parte superior do escopo e definido como nulo, que declara, mas não inicializa a variável. Na atribuição, você tem uma referência a uma variável nula indefinida que é avaliada como falsa e define a atribuição como []. Neste último, você tem uma atribuição à propriedade ada propriedade a. Você pode atribuir a uma propriedade que não existe - criando-a na atribuição, mas não pode ler a partir de uma propriedade que não existe sem que você se ReferenceErrorsinta prejudicada .
Evan Carroll

1
@EvanCarroll: é içado no topo do escopo e definido como indefinido em vez de nulo.
Mithunsatheesh # 25/14

8

O uso varé sempre uma boa idéia para impedir que as variáveis ​​atrapalhem o escopo global e as variáveis ​​entrem em conflito umas com as outras, causando substituição indesejada.


8

Sem var- variável global.

Altamente recomendado para sempre usar vardeclaração, porque init variável global no contexto local - é mau. Mas, se você precisar desse truque sujo, escreva um comentário no início da página:

/* global: varname1, varname2... */

3

Este é um código de exemplo que escrevi para você entender esse conceito:

var foo = 5; 
bar = 2;     
fooba = 3;

// Execute an anonymous function
(function() {    
    bar = 100;             //overwrites global scope bar
    var foo = 4;           //a new foo variable is created in this' function's scope
    var fooba = 900;       //same as above
    document.write(foo);   //prints 4
    document.write(bar);   //prints 100
    document.write(fooba); //prints 900
})();

document.write('<br/>');
document.write('<br/>');
document.write(foo);       //prints 5
document.write(bar);       //prints 100
document.write(fooba);     //prints 3

2
A função não é de forma alguma "anônima". De fato, é tão visivelmente nomeado quanto possível.
Ingo Bürk

Obrigado por editar sua resposta, em resposta ao comentário de Ingo Bürk, para tornar a "função anônima" realmente anônima.
Dave Burton

3

@ Chris S deu um bom exemplo, mostrando a diferença prática (e o perigo) entre vare não var. Aqui está outro, acho este particularmente perigoso, porque a diferença é visível apenas em um ambiente assíncrono, para que ele possa passar facilmente durante o teste.

Como seria de esperar, as seguintes saídas de snippet ["text"]:

function var_fun() {
  let array = []
  array.push('text')
  return array
}

console.log(var_fun())

O mesmo acontece com o seguinte trecho (observe o que faltava letantes array):

function var_fun() {
  array = []
  array.push('text')
  return array
}

console.log(var_fun())

A execução da manipulação de dados de forma assíncrona ainda produz o mesmo resultado com um único executor:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

var_fun().then(result => {console.log(result)})

Mas se comporta de maneira diferente com vários:

function var_fun() {
  array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})

No entanto, usando let:

function var_fun() {
  let array = [];
  return new Promise(resolve => resolve()).then(() => {
    array.push('text')
    return array
  })
}

[1,2,3].forEach(i => {
  var_fun().then(result => {console.log(result)})
})


Obrigado pelo exemplo @thisismydesign! Em relação aos dois últimos exemplos, por que o penúltimo exemplo registra uma matriz de 3 elementos com o texto escrito três vezes, enquanto o exemplo final registra apenas "texto" uma vez por elemento dentro da matriz? (Entendo que o último declara "matriz" como uma variável e, portanto, está no escopo local, enquanto o penúltimo exemplo o omite, tornando a "matriz" parte do escopo global implícito.) Mas, por que como isso afeta o resultado? É porque o forEach "i" itera sobre a função e todas as variáveis ​​globais?
AlmostPitt 22/09/19

2

Como alguém tentando aprender isso, é assim que eu vejo. Os exemplos acima foram talvez um pouco complicados demais para um iniciante.

Se você executar este código:

var local = true;
var global = true;


function test(){
  var local = false;
  var global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

A saída será lida como: false, false, true, true

Como ele vê as variáveis ​​na função separadas daquelas fora dela, daí o termo variável local e isso ocorreu porque usamos var na atribuição. Se você remover o var na função, ele ficará assim:

var local = true;
var global = true;


function test(){
  local = false;
  global = false;
  console.log(local)
  console.log(global)
}

test();

console.log(local);
console.log(global);

A saída é falsa, falsa, falsa, falsa

Isso ocorre porque, em vez de criar uma nova variável no escopo ou função local, ela simplesmente usa as variáveis ​​globais e as atribui novamente a false.


2

Eu vejo pessoas confusas ao declarar variáveis ​​com ou sem var e dentro ou fora da função. Aqui está um exemplo profundo que o guiará através destas etapas:

Veja o script abaixo em ação aqui em jsfiddle

a = 1;// Defined outside the function without var
var b = 1;// Defined outside the function with var
alert("Starting outside of all functions... \n \n a, b defined but c, d not defined yet: \n a:" + a + "\n b:" + b + "\n \n (If I try to show the value of the undefined c or d, console.log would throw 'Uncaught ReferenceError: c is not defined' error and script would stop running!)");

function testVar1(){
    c = 1;// Defined inside the function without var
    var d = 1;// Defined inside the function with var
    alert("Now inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 1. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};


testVar1();
alert("Run the 1. function again...");
testVar1();

function testVar2(){
    var d = 1;// Defined inside the function with var
    alert("Now inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);

    a = a + 5;
    b = b + 5;
    c = c + 5;
    d = d + 5;

    alert("After added values inside the 2. function: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n d:" + d);
};

testVar2();

alert("Now outside of all functions... \n \n Final Values: \n a:" + a + "\n b:" + b + "\n c:" + c + "\n You will not be able to see d here because then the value is requested, console.log would throw error 'Uncaught ReferenceError: d is not defined' and script would stop. \n ");
alert("**************\n Conclusion \n ************** \n \n 1. No matter declared with or without var (like a, b) if they get their value outside the function, they will preserve their value and also any other values that are added inside various functions through the script are preserved.\n 2. If the variable is declared without var inside a function (like c), it will act like the previous rule, it will preserve its value across all functions from now on. Either it got its first value in function testVar1() it still preserves the value and get additional value in function testVar2() \n 3. If the variable is declared with var inside a function only (like d in testVar1 or testVar2) it will will be undefined whenever the function ends. So it will be temporary variable in a function.");
alert("Now check console.log for the error when value d is requested next:");
alert(d);

Conclusão

  1. Não importa se declarado com ou sem var (como a, b), se eles obtiverem seu valor fora da função, eles preservarão seu valor e também quaisquer outros valores adicionados dentro de várias funções através do script serão preservados.
  2. Se a variável for declarada sem var dentro de uma função (como c), ela atuará como a regra anterior, preservando seu valor em todas as funções a partir de agora. Ou ele obteve seu primeiro valor na função testVar1 (), ainda preserva o valor e obtém valor adicional na função testVar2 ()
  3. Se a variável for declarada com var apenas dentro de uma função (como d em testVar1 ou testVar2), ela será indefinida sempre que a função terminar. Portanto, será uma variável temporária em uma função.

Obrigado por dedicar um tempo para criar um exemplo para demonstrar este tópico. O código acima está ausente na parte abaixo, portanto, você pode editar sua resposta: a = 1; // Definido fora da função sem var var b = 1; // Definido fora da função com var alert ("Iniciando fora de todas as funções ... \ n \ na, b definido, mas c, d ainda não definido: \ na: "+ a +" \ nb: "+ b +" \ n \ n (Se eu tentar mostrar o valor do c indefinido ou d, console.log lançaria o erro 'Uncaught ReferenceError: c não está definido' e o script pararia de ser executado!) ");
114018 Sankofa

1

Dentro de um código, se você usa uma variável sem usar var, o que acontece é que o var_name automaticamente é colocado no escopo global, por exemplo:

someFunction() {
    var a = some_value; /*a has local scope and it cannot be accessed when this
    function is not active*/
    b = a; /*here it places "var b" at top of script i.e. gives b global scope or
    uses already defined global variable b */
}

1

Além da questão dos escopos, algumas pessoas também mencionam a elevação , mas ninguém deu um exemplo. Aqui está um para o escopo global:

console.log(noErrorCase);
var noErrorCase = "you will reach that point";

console.log(runTimeError);
runTimeError = "you won't reach that point";


0

Sem o uso de "var", as variáveis ​​só podem definir quando definir um valor. No exemplo:

my_var;

não pode funcionar no escopo global ou em qualquer outro escopo . Deve ser com valor como:

my_var = "value";

Por outro lado, você pode definir um tipo disponível;

var my_var;

Seu valor é undefined(seu valor não é nulle não é igual a nullinteressante).


my_var;é realmente uma declaração de expressão válida.
Lexicore

É uma declaração válida se a variável for definida anteriormente. Caso contrário, lançará um erro "... não está definido".
umut

3
É uma declaração válida, independentemente de uma variável ter sido definida antes ou não. :) Uma declaração válida pode gerar um erro e não invalida a declaração .
Lexicore

Estou confuso sobre isso. O que é uma declaração válida? E você pode me dar um exemplo de instrução inválido?
umut

Terei que me desculpar - muita gramática ECMAScript ultimamente. my_var;é uma declaração de expressão válida . /my_var;seria uma declaração inválida. Mas como eu disse, isso é casuística gramatical, peço desculpas, meu comentário não foi realmente apropriado.
Lexicore

0

Você deve usar a palavra-chave var, a menos que pretenda ter a variável anexada ao objeto de janela no navegador. Aqui está um link que explica o escopo e a diferença entre o escopo glocal e o local com e sem a palavra-chave var.

Quando as variáveis ​​são definidas sem o uso da palavra-chave var, o que parece é uma operação simples de "atribuição".

Quando o valor é atribuído a uma variável em javascript, o intérprete tenta primeiro encontrar a “declaração de variável” no mesmo contexto / escopo que o da atribuição. Quando o intérprete é executado dummyVariable = 20, ele procura a declaração de dummyVariable no início da função. (Como todas as declarações de variáveis ​​são movidas para o início do contexto pelo interpretador javascript e isso é chamado de içamento)

Você também pode querer considerar içar em javascript

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.