Não consigo entender por que variáveis agem tão estranhas quando declaradas dentro de uma função.
Na
first
função declaro comlet
as variáveisb
ec
com o valor 10 :b = c = 10;
Na
second
função eu mostro:b + ", " + c
E isso mostra:
10, 10
Também na
first
função declaroa
com o valor 10 :let a = b = c = 10;
Mas na
second
função mostra um erro:Não é possível encontrar a variável:
a
Agora, na
first
função, declarod
com o valor 20 :var d = 20;
Mas na
second
função mostra o mesmo erro de antes, mas com a variáveld
:Não é possível encontrar a variável:
d
Exemplo:
function first() {
let a = b = c = 10;
var d = 20;
second();
}
function second() {
console.log(b + ", " + c); //shows "10, 10"
try{ console.log(a); } // Rreference error
catch(e){ console.error(e.message) }
try{ console.log(d); } // Reference error
catch(e){ console.error(e.message) }
}
first()
javascript
variable-declaration
intérprete de balidos
fonte
fonte
b
ec
não são prefixados com ovar
palavra-chave.a
ed
são locais parafirst
.Dim Apple, Banana, Pear As Fruit
significaDim Apple / Dim Banana / Dim Pear As Fruit
e nãoDim Apple As Fruit / ...
.Respostas:
É porque você está realmente dizendo:
E não o que você pensa que está dizendo, que é:
Você notará que, não importa quantas variáveis você adicione à sua cadeia, será apenas a primeira (a) que causará o erro.
Isso ocorre porque "let" coloca sua variável no bloco (ou "localmente", mais ou menos significa "entre colchetes") no qual você a declara.
Se você declarar uma variável sem "let", ela escopo a variável globalmente.
Portanto, na função em que você define suas variáveis, tudo obtém o valor 10 (você pode ver isso no depurador se colocar um ponto de interrupção). Se você colocar um log do console para a, b, c nessa primeira função, tudo estará bem.
Mas assim que você sai dessa função, a primeira (a) - e novamente, lembre-se, tecnicamente na ordem de atribuição, é a última - "desaparece" (novamente, você pode ver isso no depurador se você definir um ponto de interrupção na segunda função), mas os outros dois (ou quantos você adicionar) ainda estarão disponíveis.
Isso ocorre porque "let" APLICA-SE APENAS A (portanto, somente escopos locais) A PRIMEIRA VARIÁVEL - novamente, que é tecnicamente a última a ser declarada e atribuída um valor - na cadeia. O resto tecnicamente não tem "let" na frente deles. Portanto, eles são tecnicamente declarados globalmente (ou seja, no objeto global), e é por isso que eles aparecem na sua segunda função.
Experimente: remova a palavra-chave "let". Todos os seus vars estarão agora disponíveis.
"var" tem um efeito de escopo local semelhante, mas difere em como a variável é "içada", o que é algo que você definitivamente deve entender, mas que não está diretamente envolvido com sua pergunta.
(BTW, essa pergunta seria inútil para desenvolvedores JS profissionais o suficiente para torná-la uma boa).
É altamente recomendável que você gaste tempo com as diferenças de como as variáveis podem ser declaradas em JS: sem uma palavra-chave, com "let" e "var".
fonte
var
maislet
no contexto de esta resposta? Eu não entendovar
pode ser propenso a erros se usado de forma descuidada. Verifique este violinovar
tem alguma vantagemlet
? Deixe-me esclarecer: um contexto moderno quando ambos são opções e estou pedindo um código que se deve escrever. Quando perguntei isso antes, recebi respostas sobre "você pode declarar novamente uma variável comvar
"; nesse caso, tenho que lembrar às pessoas que você não deve declarar variáveis novamente . Isso é um bug ou um erro na lógica do código - então o benefício da re-declaração é ... que permite que você escreva um código com defeito. Ainda não vi nenhuma razão sensata a favor devar
quandolet
também é uma opção.Na função
first()
, variáveisb
ec
são criadas em tempo real, sem usarvar
oulet
.É diferente de
Eles se tornam globais implícitos. É por isso que eles estão disponíveis em
second()
Da documentação
Para evitar isso, você pode usar
"use strict"
isso fornecerá erros quando alguém usar uma variável não declaradafonte
let a = 10, b = 10, c = 10;
oulet a, b, c; a = b = c = 10;
seria a maneira correta de declarar as variáveis.b
não será avaliada / alcançada, ocorrerá um erro na linhalet a = b = c = 10;
, lido da direita para a esquerda .c
sendo a primeira variável causandoReferenceError
, o restante da linha não será executado (o script parou)let a = 10, b = a, c = b;
é válido tambémAntes de chamar as coisas de estranhas, vamos conhecer alguns princípios básicos primeiro:
var e let são usados para declaração de variáveis em JavaScript. Por exemplo,
Variáveis também podem ser declaradas sem usar
var
oulet
. Por exemplo,Agora, a diferença entre as abordagens acima é a seguinte:
var
é o escopo da funçãoe
let
tem escopo definido no bloco.Agora, de acordo com esses conceitos, vamos dar uma olhada no código em questão:
fonte
var
palavra - chave se torna global, independentemente de onde ela é declarada" deveria ser "o escopo ... se torna" ou "o escopos ... tornam-se " . Usar as palavras exatas de outra pessoa requer citação, seja daqui ou de outro lugar. meta.stackexchange.com/q/160071/211183Variáveis que usam a
let
palavra-chave devem estar disponíveis apenas dentro do escopo do bloco e não disponíveis em uma função externa ...Cada variável que você está declarando dessa maneira não está usando
let
ouvar
. Está faltando uma vírgula na declaração das variáveis.Não é recomendável declarar uma variável sem a
var
palavra - chave. Pode substituir acidentalmente uma variável global existente. O escopo das variáveis declaradas sem avar
palavra - chave se torna global, independentemente de onde ela é declarada. Variáveis globais podem ser acessadas de qualquer lugar da página da web.fonte
É porque, quando você não usa
let
ouvar
então a variável está sendo declarada em tempo real, é melhor você declarar como segue.fonte
O problema estranho é causado por regras de escopo no JavaScript
Supondo que você queira declarar 3 variáveis locais inicializadas com o mesmo valor (100). O seu primeiro () será parecido abaixo. Nesse caso, second () não terá acesso a nenhuma das variáveis porque elas são locais para first ()
No entanto, se você deseja variáveis globais , o seu primeiro () será semelhante a seguir. Nesse caso, o segundo terá acesso a todas as variáveis porque elas estão no escopo global
Variáveis locais (também conhecidas como acessíveis no bloco de códigos onde são declaradas).
Um bloco de código é qualquer {} com linha (s) de código entre.
Variáveis globais (também conhecidas como acessíveis no escopo global).
Essas variáveis estão anexadas ao objeto global. O objeto global depende do ambiente. É o objeto de janela nos navegadores.
Nota especial: você pode declarar variáveis no JavaScript sem usar as palavras-chave var, let, const. Uma variável declarada dessa maneira é anexada ao objeto global, portanto acessível no escopo global.
a = 100 // is valid and is in global scope
Alguns artigos para leitura adicional: https://www.sitepoint.com/demystifying-javascript-variable-scope-hoisting/ https://scotch.io/tutorials/understanding-scope-in-javascript https: //www.digitalocean .com / community / tutoriais / compreensão-variáveis-escopo-levantamento-em-javascript
fonte
A principal diferença está nas regras de escopo. As variáveis declaradas pela palavra-chave var têm o escopo definido para o corpo da função imediata (daí o escopo da função) enquanto as variáveis permitidas têm o escopo definido para o bloco de fechamento imediato indicado por {} (portanto, o escopo do bloco). E quando você diz
c e b têm uma vida útil tão divertida, mas apenas têm uma extensão de bloco e, se você tentar acessar a referenciando, sempre mostra erro, mas c e b são globalmente, portanto não o fazem. Você perceberá que não importa quantas variáveis adicionadas à sua cadeia, ela será apenas a primeira (a) que causa o erro. Isso ocorre porque "let" coloca sua variável no bloco (ou "localmente", mais ou menos significa "entre parênteses") no qual você a declara. Se você declarar uma variável sem "let", ela escopo a variável globalmente.Então, na função em que você define suas variáveis, tudo obtém o valor 10 (você pode ver isso no depurador se colocar um ponto de interrupção). Se você colocar um log do console para a, b, c nessa primeira função, tudo ficará bem. Mas, assim que você sair dessa função, a primeira (a) - e novamente, lembre-se de que,
fonte
Aqui estão os três aspectos interessantes das declarações de variáveis no JavaScript:
var restringe o escopo da variável ao bloco em que está definida. ( 'var' é para escopo local .)
let permite a substituição temporária do valor de uma variável externa dentro de um bloco.
Simplesmente declarar uma variável sem var ou let tornará a variável global, independentemente de onde for declarada.
Aqui está uma demonstração do let , que é a mais recente adição ao idioma:
Resultado:
Explicação:
As variáveis a e b foram declaradas dentro ' first () ', sem var ou deixar palavras-chave.
Portanto, a e b são globais e, portanto, são acessíveis durante todo o programa.
Na função denominada 'second' , a instrução 'let a = 5' define temporariamente o valor de ' a ' para ' 5 ', apenas no escopo da função.
Fora do escopo de ' second () ', ou seja, no escopo global, o valor de ' a ' será como definido anteriormente.
fonte