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 var
palavra - 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?
Respostas:
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,
var
criará 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á):Se você não estiver realizando uma tarefa, precisará usar
var
:fonte
Há uma diferença .
var x = 1
declara variávelx
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 comx
relação à cadeia de escopo. Se o encontrar em qualquer lugar dessa cadeia de escopo, ele executará a atribuição; se não encontrarx
, somente criax
propriedade 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 = 1
ex = 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 .
fonte
delete
uma variável declarada em var com algumeval
hack. Se eu me lembrar do truque exato, postarei aqui.var someObject = {}
esomeObject.someProperty = 5
? SesomeProperty
tornaria global, enquanto o objeto de que é propriedade permanece local?false
) , você pode ler sobre isso em relação aoObject.defineProperty
eObject.getOwnPropertyDescriptor
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.
fonte
outer
onde você definevar global = false;
?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 linhavar global = global
, nesse caso, o escopo mais próximo ao procurar o valor deglobal
seria um nível acima no escopo da janela global.Quando o Javascript é executado em um navegador, todo o seu código é cercado por uma declaração with, assim:
Mais informações sobre
with
- MDNComo
var
declara uma variável no escopo atual , não há diferença entre declararvar
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
var
permite 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:
var
declara uma variável no escopo atualwindow
var
declarações implícitasvar
no escopo global (janela)var
é o mesmo que omiti-la.var
não é a mesma coisa que declarar uma variável semvar
var
explicitamente porque é uma boa práticafonte
let
no ES6.Sempre use a
var
palavra-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 :fonte
good coding practice
sempre é motivo suficiente se for uma prática recomendada, que é e por vários autores de Javascript.Aqui está um bom exemplo de como você pode ser pego por não declarar variáveis locais com
var
:(
i
é redefinido a cada iteração do loop, pois não é declarado localmente nofor
loop, mas globalmente) eventualmente resultando em loop infinitofonte
Eu diria que é melhor usar
var
na 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
var
declarar uma variável, ela estará no escopo global.Para mais informações, você pode pesquisar "JavaScript da cadeia de escopo" no Google.
fonte
Não use
var
!var
foi a maneira pré-ES6 de declarar uma variável. Estamos agora no futuro e você deve codificar como tal.Use
const
elet
const
deve 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 serconst
.let
deve ser usado para qualquer variável que espera ser reatribuída. Isso inclui um loop for. Se você escrevervarName =
além da inicialização, uselet
.Ambos têm escopo no nível do bloco, como esperado na maioria dos outros idiomas.
fonte
outra diferença, por exemplo
enquanto
fonte
var
?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 à propriedadea
da propriedadea
. 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ê seReferenceError
sinta prejudicada .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.fonte
Sem
var
- variável global.Altamente recomendado para sempre usar
var
declaraçã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:fonte
Este é um código de exemplo que escrevi para você entender esse conceito:
fonte
@ Chris S deu um bom exemplo, mostrando a diferença prática (e o perigo) entre
var
e nãovar
. 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"]
:O mesmo acontece com o seguinte trecho (observe o que faltava
let
antesarray
):A execução da manipulação de dados de forma assíncrona ainda produz o mesmo resultado com um único executor:
Mas se comporta de maneira diferente com vários:
No entanto, usando let:
fonte
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:
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:
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.
fonte
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
fonte
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:
fonte
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:
fonte
Sem o uso de "var", as variáveis só podem definir quando definir um valor. No exemplo:
não pode funcionar no escopo global ou em qualquer outro escopo . Deve ser com valor como:
Por outro lado, você pode definir um tipo disponível;
Seu valor é
undefined
(seu valor não énull
e não é igual anull
interessante).fonte
my_var;
é realmente uma declaração de expressão válida.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.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
fonte