From 496af688d2e1f8d867a3159bf9c386155a128a12 Mon Sep 17 00:00:00 2001 From: Diogo Marciano Date: Mon, 9 Nov 2026 01:31:10 -0300 Subject: [PATCH] Translate "Variable scope, closure" article to Portuguese Co-Authored-By: Claude Sonnet 5 --- .../1-closure-latest-changes/solution.md | 6 +- .../1-closure-latest-changes/task.md | 10 +- .../10-make-army/_js.view/solution.js | 4 +- .../10-make-army/_js.view/source.js | 10 +- .../03-closure/10-make-army/_js.view/test.js | 6 +- .../10-make-army/lexenv-makearmy-empty.svg | 2 +- .../lexenv-makearmy-for-fixed.svg | 2 +- .../lexenv-makearmy-while-fixed.svg | 2 +- .../03-closure/10-make-army/solution.md | 56 ++-- .../03-closure/10-make-army/task.md | 26 +- .../2-closure-variable-access/solution.md | 8 +- .../2-closure-variable-access/task.md | 14 +- .../3-counter-independent/solution.md | 6 +- .../03-closure/3-counter-independent/task.md | 6 +- .../4-counter-object-independent/solution.md | 4 +- .../4-counter-object-independent/task.md | 6 +- .../03-closure/5-function-in-if/solution.md | 4 +- .../03-closure/5-function-in-if/task.md | 4 +- .../03-closure/6-closure-sum/solution.md | 6 +- .../03-closure/6-closure-sum/task.md | 8 +- .../03-closure/7-let-scope/solution.md | 20 +- .../03-closure/7-let-scope/task.md | 6 +- .../_js.view/source.js | 4 +- .../_js.view/test.js | 4 +- .../8-filter-through-function/solution.md | 4 +- .../8-filter-through-function/task.md | 20 +- .../9-sort-by-field/_js.view/source.js | 2 +- .../9-sort-by-field/_js.view/test.js | 6 +- .../03-closure/9-sort-by-field/task.md | 16 +- .../03-closure/article.md | 274 +++++++++--------- .../closure-function-declaration.svg | 2 +- .../closure-makecounter-nested-call-2.svg | 2 +- .../03-closure/closure-makecounter.svg | 2 +- .../03-closure/closure-variable-phrase.svg | 2 +- .../lexenv-nested-makecounter-2.svg | 2 +- .../lexenv-nested-makecounter-6.svg | 2 +- .../lexical-environment-global-2.svg | 2 +- .../lexical-environment-global-3.svg | 2 +- .../03-closure/lexical-environment-global.svg | 2 +- .../03-closure/lexical-environment-simple.svg | 2 +- images.yml | 73 +++++ 41 files changed, 356 insertions(+), 283 deletions(-) diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md index 7cbd85ab7..8f8a8333c 100644 --- a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/solution.md @@ -1,5 +1,5 @@ -The answer is: **Pete**. +A resposta é: **Pete**. -A function gets outer variables as they are now, it uses the most recent values. +Uma função recebe as variáveis externas como elas estão agora, ela usa os valores mais recentes. -Old variable values are not saved anywhere. When a function wants a variable, it takes the current value from its own Lexical Environment or the outer one. +Valores antigos de variáveis não são salvos em lugar nenhum. Quando uma função quer uma variável, ela pega o valor atual do seu próprio Ambiente Léxico ou do externo. diff --git a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md index 819189773..674dd44e8 100644 --- a/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md +++ b/1-js/06-advanced-functions/03-closure/1-closure-latest-changes/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Does a function pickup latest changes? +# Uma função pega as mudanças mais recentes? -The function sayHi uses an external variable name. When the function runs, which value is it going to use? +A função sayHi usa uma variável externa name. Quando a função roda, qual valor ela vai usar? ```js let name = "John"; @@ -15,9 +15,9 @@ function sayHi() { name = "Pete"; -sayHi(); // what will it show: "John" or "Pete"? +sayHi(); // o que vai mostrar: "John" ou "Pete"? ``` -Such situations are common both in browser and server-side development. A function may be scheduled to execute later than it is created, for instance after a user action or a network request. +Situações assim são comuns tanto no desenvolvimento para navegador quanto no lado do servidor. Uma função pode ser agendada para executar depois de ser criada, por exemplo, após uma ação do usuário ou uma requisição de rede. -So, the question is: does it pick up the latest changes? +Então, a pergunta é: ela pega as mudanças mais recentes? diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js index a26578ae1..f7e15f8af 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js +++ b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/solution.js @@ -3,8 +3,8 @@ function makeArmy() { let shooters = []; for(let i = 0; i < 10; i++) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // função shooter + alert( i ); // deveria mostrar seu número }; shooters.push(shooter); } diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js index 7c7aaa1e3..d1bc4d0a4 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/source.js @@ -3,8 +3,8 @@ function makeArmy() { let i = 0; while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // função shooter + alert( i ); // deveria mostrar seu número }; shooters.push(shooter); i++; @@ -16,7 +16,7 @@ function makeArmy() { /* let army = makeArmy(); -army[0](); // the shooter number 0 shows 10 -army[5](); // and number 5 also outputs 10... -// ... all shooters show 10 instead of their 0, 1, 2, 3... +army[0](); // o shooter número 0 mostra 10 +army[5](); // e o número 5 também exibe 10... +// ... todos os shooters mostram 10 em vez de 0, 1, 2, 3... */ diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js index b61e6e4db..365361010 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js +++ b/1-js/06-advanced-functions/03-closure/10-make-army/_js.view/test.js @@ -1,19 +1,19 @@ describe("army", function() { let army; - + before(function() { army = makeArmy(); window.alert = sinon.stub(window, "alert"); }); - it("army[0] shows 0", function() { + it("army[0] mostra 0", function() { army[0](); assert(alert.calledWith(0)); }); - it("army[5] shows 5", function() { + it("army[5] mostra 5", function() { army[5](); assert(alert.calledWith(5)); }); diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg index f8c7bd6ac..26fbbe75e 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg @@ -1 +1 @@ -outer<empty>makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment<empty><empty><empty>i: 10 \ No newline at end of file +outer<empty>makeArmy() Ambiente Léxicoiteração do while Ambiente Léxico<empty><empty><empty>i: 10 \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg index 7611d0ef8..fde5ba3e9 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg @@ -1 +1 @@ -outermakeArmy() LexicalEnvironmentfor iteration LexicalEnvironmenti: 0i: 1i: 2i: 10... \ No newline at end of file +outermakeArmy() Ambiente Léxicoiteração do for Ambiente Léxicoi: 0i: 1i: 2i: 10... \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg index d83ecbe76..bf539c06b 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg +++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg @@ -1 +1 @@ -outerj: 0j: 1j: 2j: 10...makeArmy() LexicalEnvironmentwhile iteration LexicalEnvironment \ No newline at end of file +outerj: 0j: 1j: 2j: 10...makeArmy() Ambiente Léxicoiteração do while Ambiente Léxico \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md index 9d99aa717..1f911ce89 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md +++ b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md @@ -1,14 +1,14 @@ -Let's examine what exactly happens inside `makeArmy`, and the solution will become obvious. +Vamos examinar o que exatamente acontece dentro de `makeArmy`, e a solução vai ficar óbvia. -1. It creates an empty array `shooters`: +1. Ele cria um array vazio `shooters`: ```js let shooters = []; ``` -2. Fills it with functions via `shooters.push(function)` in the loop. +2. Preenche ele com funções via `shooters.push(function)` no laço. - Every element is a function, so the resulting array looks like this: + Cada elemento é uma função, então o array resultante fica assim: ```js no-beautify shooters = [ @@ -25,40 +25,40 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco ]; ``` -3. The array is returned from the function. +3. O array é retornado pela função. - Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls it. + Então, mais tarde, a chamada a qualquer membro, ex.: `army[5]()`, vai pegar o elemento `army[5]` do array (que é uma função) e chamá-lo. - Now why do all such functions show the same value, `10`? + Agora, por que todas essas funções mostram o mesmo valor, `10`? - That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment. + Isso acontece porque não existe uma variável local `i` dentro das funções `shooter`. Quando uma dessas funções é chamada, ela pega `i` do seu ambiente léxico externo. - Then, what will be the value of `i`? + Então, qual vai ser o valor de `i`? - If we look at the source: + Se olharmos o código-fonte: ```js function makeArmy() { ... let i = 0; while (i < 10) { - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // função shooter + alert( i ); // deveria mostrar seu número }; - shooters.push(shooter); // add function to the array + shooters.push(shooter); // adiciona a função ao array i++; } ... } ``` - We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `i=10`). + Podemos ver que todas as funções `shooter` são criadas no ambiente léxico da função `makeArmy()`. Mas quando `army[5]()` é chamada, `makeArmy` já terminou seu trabalho, e o valor final de `i` é `10` (`while` para em `i=10`). - As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`. + Como resultado, todas as funções `shooter` pegam o mesmo valor do ambiente léxico externo, que é o último valor, `i=10`. ![](lexenv-makearmy-empty.svg) - As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this: + Como você pode ver acima, em cada iteração de um bloco `while {...}`, um novo ambiente léxico é criado. Então, para corrigir isso, podemos copiar o valor de `i` para uma variável dentro do bloco `while {...}`, assim: ```js run function makeArmy() { @@ -69,8 +69,8 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco *!* let j = i; */!* - let shooter = function() { // shooter function - alert( *!*j*/!* ); // should show its number + let shooter = function() { // função shooter + alert( *!*j*/!* ); // deveria mostrar seu número }; shooters.push(shooter); i++; @@ -81,18 +81,18 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco let army = makeArmy(); - // Now the code works correctly + // Agora o código funciona corretamente army[0](); // 0 army[5](); // 5 ``` - Here `let j = i` declares an "iteration-local" variable `j` and copies `i` into it. Primitives are copied "by value", so we actually get an independent copy of `i`, belonging to the current loop iteration. + Aqui, `let j = i` declara uma variável "local à iteração", `j`, e copia `i` para ela. Primitivos são copiados "por valor", então na verdade obtemos uma cópia independente de `i`, pertencente à iteração atual do laço. - The shooters work correctly, because the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds to the current loop iteration: + Os shooters funcionam corretamente, porque o valor de `i` agora vive um pouco mais perto. Não no Ambiente Léxico de `makeArmy()`, mas no Ambiente Léxico que corresponde à iteração atual do laço: ![](lexenv-makearmy-while-fixed.svg) - Such a problem could also be avoided if we used `for` in the beginning, like this: + Esse problema também poderia ser evitado se usássemos `for` desde o início, assim: ```js run demo function makeArmy() { @@ -102,8 +102,8 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco *!* for(let i = 0; i < 10; i++) { */!* - let shooter = function() { // shooter function - alert( i ); // should show its number + let shooter = function() { // função shooter + alert( i ); // deveria mostrar seu número }; shooters.push(shooter); } @@ -117,13 +117,13 @@ Let's examine what exactly happens inside `makeArmy`, and the solution will beco army[5](); // 5 ``` - That's essentially the same, because `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration. + Isso é essencialmente a mesma coisa, porque o `for`, em cada iteração, gera um novo ambiente léxico, com sua própria variável `i`. Então o `shooter` gerado em cada iteração referencia seu próprio `i`, daquela mesma iteração. ![](lexenv-makearmy-for-fixed.svg) -Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder -- was it worth that? +Agora, já que você se esforçou tanto pra ler isso tudo, e a receita final é tão simples -- só usar `for` -- você deve estar se perguntando -- valeu a pena? -Well, if you could easily answer the question, you wouldn't read the solution. So, hopefully this task must have helped you to understand things a bit better. +Bom, se você conseguisse responder a pergunta facilmente, não leria a solução. Então, esperamos que essa tarefa tenha ajudado você a entender as coisas um pouco melhor. -Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios, where such problems are real. +Além disso, existem sim casos em que se prefere `while` a `for`, e outros cenários, onde esses problemas são reais. diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/task.md b/1-js/06-advanced-functions/03-closure/10-make-army/task.md index f50c7dc20..3ae5cf59b 100644 --- a/1-js/06-advanced-functions/03-closure/10-make-army/task.md +++ b/1-js/06-advanced-functions/03-closure/10-make-army/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Army of functions +# Exército de funções -The following code creates an array of `shooters`. +O código a seguir cria um array de `shooters`. -Every function is meant to output its number. But something is wrong... +Cada função deveria exibir seu número. Mas algo está errado... ```js run function makeArmy() { @@ -14,28 +14,28 @@ function makeArmy() { let i = 0; while (i < 10) { - let shooter = function() { // create a shooter function, - alert( i ); // that should show its number + let shooter = function() { // cria uma função shooter, + alert( i ); // que deveria mostrar seu número }; - shooters.push(shooter); // and add it to the array + shooters.push(shooter); // e a adiciona ao array i++; } - // ...and return the array of shooters + // ...e retorna o array de shooters return shooters; } let army = makeArmy(); *!* -// all shooters show 10 instead of their numbers 0, 1, 2, 3... -army[0](); // 10 from the shooter number 0 -army[1](); // 10 from the shooter number 1 -army[2](); // 10 ...and so on. +// todos os shooters mostram 10 em vez de seus números 0, 1, 2, 3... +army[0](); // 10 do shooter número 0 +army[1](); // 10 do shooter número 1 +army[2](); // 10 ...e assim por diante. */!* ``` -Why do all of the shooters show the same value? +Por que todos os shooters mostram o mesmo valor? -Fix the code so that they work as intended. +Corrija o código para que eles funcionem como pretendido. diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md index 0a522132f..d95685ffc 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/solution.md @@ -1,9 +1,9 @@ -The answer is: **Pete**. +A resposta é: **Pete**. -The `work()` function in the code below gets `name` from the place of its origin through the outer lexical environment reference: +A função `work()` no código abaixo pega `name` do seu lugar de origem, através da referência do ambiente léxico externo: ![](lexenv-nested-work.svg) -So, the result is `"Pete"` here. +Então, o resultado aqui é `"Pete"`. -But if there were no `let name` in `makeWorker()`, then the search would go outside and take the global variable as we can see from the chain above. In that case the result would be `"John"`. +Mas se não houvesse `let name` em `makeWorker()`, então a busca iria para fora e pegaria a variável global, como podemos ver pela cadeia acima. Nesse caso, o resultado seria `"John"`. diff --git a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md index d12a385c8..8b62fa1e3 100644 --- a/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md +++ b/1-js/06-advanced-functions/03-closure/2-closure-variable-access/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Which variables are available? +# Quais variáveis estão disponíveis? -The function `makeWorker` below makes another function and returns it. That new function can be called from somewhere else. +A função `makeWorker` abaixo cria outra função e a retorna. Essa nova função pode ser chamada de algum outro lugar. -Will it have access to the outer variables from its creation place, or the invocation place, or both? +Ela vai ter acesso às variáveis externas do seu lugar de criação, do lugar de invocação, ou dos dois? ```js function makeWorker() { @@ -19,11 +19,11 @@ function makeWorker() { let name = "John"; -// create a function +// cria uma função let work = makeWorker(); -// call it -work(); // what will it show? +// a chama +work(); // o que vai mostrar? ``` -Which value it will show? "Pete" or "John"? +Qual valor ela vai mostrar? "Pete" ou "John"? diff --git a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md index 25ecbea4c..2897f866e 100644 --- a/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md +++ b/1-js/06-advanced-functions/03-closure/3-counter-independent/solution.md @@ -1,5 +1,5 @@ -The answer: **0,1.** +A resposta: **0,1.** -Functions `counter` and `counter2` are created by different invocations of `makeCounter`. +As funções `counter` e `counter2` são criadas por invocações diferentes de `makeCounter`. -So they have independent outer Lexical Environments, each one has its own `count`. +Então elas têm Ambientes Léxicos externos independentes, cada uma com seu próprio `count`. diff --git a/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md b/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md index e8c17dd31..b5a53554a 100644 --- a/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/3-counter-independent/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Are counters independent? +# Os contadores são independentes? -Here we make two counters: `counter` and `counter2` using the same `makeCounter` function. +Aqui criamos dois contadores: `counter` e `counter2`, usando a mesma função `makeCounter`. -Are they independent? What is the second counter going to show? `0,1` or `2,3` or something else? +Eles são independentes? O que o segundo contador vai mostrar? `0,1` ou `2,3` ou outra coisa? ```js function makeCounter() { diff --git a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md index cd4e641e4..f54eac9b7 100644 --- a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md +++ b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/solution.md @@ -1,7 +1,7 @@ -Surely it will work just fine. +Com certeza vai funcionar direitinho. -Both nested functions are created within the same outer Lexical Environment, so they share access to the same `count` variable: +As duas funções aninhadas são criadas dentro do mesmo Ambiente Léxico externo, então elas compartilham acesso à mesma variável `count`: ```js run function Counter() { diff --git a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md index d770b0ffc..a51f6b687 100644 --- a/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/4-counter-object-independent/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Counter object +# Objeto contador -Here a counter object is made with the help of the constructor function. +Aqui um objeto contador é criado com a ajuda de uma função construtora. -Will it work? What will it show? +Vai funcionar? O que vai mostrar? ```js function Counter() { diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md index e2e7a91b3..bc5c4db45 100644 --- a/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md +++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/solution.md @@ -1,3 +1,3 @@ -The result is **an error**. +O resultado é **um erro**. -The function `sayHi` is declared inside the `if`, so it only lives inside it. There is no `sayHi` outside. \ No newline at end of file +A função `sayHi` é declarada dentro do `if`, então ela só vive dentro dele. Não existe `sayHi` fora. diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md index 4e386eec5..5358342b2 100644 --- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md +++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md @@ -1,9 +1,9 @@ importance: 5 --- -# Function in if +# Função no if -Look at the code. What will be the result of the call at the last line? +Olhe o código. Qual vai ser o resultado da chamada na última linha? ```js run let phrase = "Hello"; diff --git a/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md index a6679cd20..39c8fd0ae 100644 --- a/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md +++ b/1-js/06-advanced-functions/03-closure/6-closure-sum/solution.md @@ -1,12 +1,12 @@ -For the second parentheses to work, the first ones must return a function. +Para o segundo parênteses funcionar, o primeiro precisa retornar uma função. -Like this: +Assim: ```js run function sum(a) { return function(b) { - return a + b; // takes "a" from the outer lexical environment + return a + b; // pega "a" do ambiente léxico externo }; } diff --git a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md index b45758562..ee1c5a1de 100644 --- a/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md +++ b/1-js/06-advanced-functions/03-closure/6-closure-sum/task.md @@ -2,13 +2,13 @@ importance: 4 --- -# Sum with closures +# Soma com closures -Write function `sum` that works like this: `sum(a)(b) = a+b`. +Escreva a função `sum` que funcione assim: `sum(a)(b) = a+b`. -Yes, exactly this way, using double parentheses (not a mistype). +Sim, exatamente desse jeito, usando parênteses duplos (não é um erro de digitação). -For instance: +Por exemplo: ```js sum(1)(2) = 3 diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md index b16b35290..9ff2fc0b7 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -1,6 +1,6 @@ -The result is: **error**. +O resultado é: **erro**. -Try running it: +Tente rodar: ```js run let x = 1; @@ -15,20 +15,20 @@ function func() { func(); ``` -In this example we can observe the peculiar difference between a "non-existing" and "uninitialized" variable. +Neste exemplo podemos observar a diferença peculiar entre uma variável "inexistente" e uma "não inicializada". -As you may have read in the article [](info:closure), a variable starts in the "uninitialized" state from the moment when the execution enters a code block (or a function). And it stays uninitalized until the corresponding `let` statement. +Como você deve ter lido no artigo [](info:closure), uma variável começa no estado "não inicializado" a partir do momento em que a execução entra num bloco de código (ou numa função). E ela continua não inicializada até a instrução `let` correspondente. -In other words, a variable technically exists, but can't be used before `let`. +Em outras palavras, a variável tecnicamente existe, mas não pode ser usada antes do `let`. -The code above demonstrates it. +O código acima demonstra isso. ```js function func() { *!* - // the local variable x is known to the engine from the beginning of the function, - // but "uninitialized" (unusable) until let ("dead zone") - // hence the error + // o motor sabe da variável local x desde o início da função, + // mas ela está "não inicializada" (inutilizável) até o let ("zona morta") + // daí o erro */!* console.log(x); // ReferenceError: Cannot access 'x' before initialization @@ -37,4 +37,4 @@ function func() { } ``` -This zone of temporary unusability of a variable (from the beginning of the code block till `let`) is sometimes called the "dead zone". +Essa zona de inutilização temporária de uma variável (desde o início do bloco de código até o `let`) às vezes é chamada de "zona morta" (*dead zone*). diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md index fb7445e66..f1f03240f 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/task.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/task.md @@ -2,9 +2,9 @@ importance: 4 --- -# Is variable visible? +# A variável é visível? -What will be the result of this code? +Qual vai ser o resultado deste código? ```js let x = 1; @@ -18,4 +18,4 @@ function func() { func(); ``` -P.S. There's a pitfall in this task. The solution is not obvious. +P.S. Tem uma pegadinha nessa tarefa. A solução não é óbvia. diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js index 74989df28..ff414a6e8 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/source.js @@ -2,9 +2,9 @@ let arr = [1, 2, 3, 4, 5, 6, 7]; function inBetween(a, b) { - // ...your code... + // ...seu código... } function inArray(arr) { - // ...your code... + // ...seu código... } diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js index 86d2d3b48..46437e786 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/_js.view/test.js @@ -2,7 +2,7 @@ describe("inArray", function() { let arr = [1, 2, 3, 4, 5, 6, 7]; - it("returns the filter for values in array", function() { + it("retorna o filtro para valores no array", function() { let filter = inArray(arr); assert.isTrue(filter(5)); @@ -13,7 +13,7 @@ describe("inArray", function() { describe("inBetween", function() { - it("returns the filter for values between", function() { + it("retorna o filtro para valores entre", function() { let filter = inBetween(3, 6); assert.isTrue(filter(5)); assert.isFalse(filter(0)); diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md index 46c5514a8..8ea7550f6 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/solution.md @@ -1,5 +1,5 @@ -# Filter inBetween +# Filtro inBetween ```js run function inBetween(a, b) { @@ -12,7 +12,7 @@ let arr = [1, 2, 3, 4, 5, 6, 7]; alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6 ``` -# Filter inArray +# Filtro inArray ```js run demo function inArray(arr) { diff --git a/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md b/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md index d1c39f949..6b91aafab 100644 --- a/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md +++ b/1-js/06-advanced-functions/03-closure/8-filter-through-function/task.md @@ -2,24 +2,24 @@ importance: 5 --- -# Filter through function +# Filtra através de uma função -We have a built-in method `arr.filter(f)` for arrays. It filters all elements through the function `f`. If it returns `true`, then that element is returned in the resulting array. +Temos um método nativo `arr.filter(f)` para arrays. Ele filtra todos os elementos através da função `f`. Se ela retornar `true`, então esse elemento é incluído no array resultante. -Make a set of "ready to use" filters: +Faça um conjunto de filtros "prontos pra usar": -- `inBetween(a, b)` -- between `a` and `b` or equal to them (inclusively). -- `inArray([...])` -- in the given array. +- `inBetween(a, b)` -- entre `a` e `b` ou igual a eles (de forma inclusiva). +- `inArray([...])` -- está no array dado. -The usage must be like this: +O uso deve ser assim: -- `arr.filter(inBetween(3,6))` -- selects only values between 3 and 6. -- `arr.filter(inArray([1,2,3]))` -- selects only elements matching with one of the members of `[1,2,3]`. +- `arr.filter(inBetween(3,6))` -- seleciona só os valores entre 3 e 6. +- `arr.filter(inArray([1,2,3]))` -- seleciona só os elementos que correspondem a um dos membros de `[1,2,3]`. -For instance: +Por exemplo: ```js -/* .. your code for inBetween and inArray */ +/* .. seu código para inBetween e inArray */ let arr = [1, 2, 3, 4, 5, 6, 7]; alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6 diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js index 23b433834..7719ff39d 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js @@ -1,5 +1,5 @@ function byField(fieldName){ - // Your code goes here. + // Seu código vai aqui. } diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js index 802f28c4d..0c4ba5d9b 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js @@ -6,7 +6,7 @@ describe("byField", function(){ { name: "Ann", age: 19, surname: "Hathaway" }, ]; - it("sorts users by name", function(){ + it("ordena usuários por name", function(){ let nameSortedKey = [ { name: "Ann", age: 19, surname: "Hathaway" }, { name: "John", age: 20, surname: "Johnson"}, @@ -16,7 +16,7 @@ describe("byField", function(){ assert.deepEqual(nameSortedKey, nameSortedAnswer); }); - it("sorts users by age", function(){ + it("ordena usuários por age", function(){ let ageSortedKey = [ { name: "Pete", age: 18, surname: "Peterson" }, { name: "Ann", age: 19, surname: "Hathaway" }, @@ -26,7 +26,7 @@ describe("byField", function(){ assert.deepEqual(ageSortedKey, ageSortedAnswer); }); - it("sorts users by surname", function(){ + it("ordena usuários por surname", function(){ let surnameSortedKey = [ { name: "Ann", age: 19, surname: "Hathaway" }, { name: "John", age: 20, surname: "Johnson"}, diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md b/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md index 08fb5cc34..237d2a11e 100644 --- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md +++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Sort by field +# Ordenar por campo -We've got an array of objects to sort: +Temos um array de objetos para ordenar: ```js let users = [ @@ -14,23 +14,23 @@ let users = [ ]; ``` -The usual way to do that would be: +A forma normal de fazer isso seria: ```js -// by name (Ann, John, Pete) +// por name (Ann, John, Pete) users.sort((a, b) => a.name > b.name ? 1 : -1); -// by age (Pete, Ann, John) +// por age (Pete, Ann, John) users.sort((a, b) => a.age > b.age ? 1 : -1); ``` -Can we make it even less verbose, like this? +Será que podemos deixar isso ainda menos verboso, assim? ```js users.sort(byField('name')); users.sort(byField('age')); ``` -So, instead of writing a function, just put `byField(fieldName)`. +Ou seja, em vez de escrever uma função, só colocar `byField(fieldName)`. -Write the function `byField` that can be used for that. +Escreva a função `byField` que possa ser usada para isso. diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index cb43a7968..fad431cc3 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,75 +1,75 @@ -# Variable scope, closure +# Escopo de variável, closure -JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at any moment, passed as an argument to another function, and then called from a totally different place of code later. +O JavaScript é uma linguagem muito orientada a funções. Ele nos dá muita liberdade. Uma função pode ser criada a qualquer momento, passada como argumento para outra função, e então chamada depois, a partir de um lugar totalmente diferente do código. -We already know that a function can access variables outside of it ("outer" variables). +Já sabemos que uma função pode acessar variáveis fora dela (variáveis "externas"). -But what happens if outer variables change since a function is created? Will the function get newer values or the old ones? +Mas o que acontece se as variáveis externas mudarem depois que a função é criada? A função vai pegar os valores mais novos ou os antigos? -And what if a function is passed along as an argument and called from another place of code, will it get access to outer variables at the new place? +E se uma função for passada adiante como argumento e chamada de outro lugar do código, ela vai ter acesso às variáveis externas no novo lugar? -Let's expand our knowledge to understand these scenarios and more complex ones. +Vamos expandir nosso conhecimento para entender esses cenários e outros mais complexos. -```smart header="We'll talk about `let/const` variables here" -In JavaScript, there are 3 ways to declare a variable: `let`, `const` (the modern ones), and `var` (the remnant of the past). +```smart header="Vamos falar sobre variáveis `let/const` aqui" +No JavaScript, existem 3 formas de declarar uma variável: `let`, `const` (as modernas), e `var` (o resquício do passado). -- In this article we'll use `let` variables in examples. -- Variables, declared with `const`, behave the same, so this article is about `const` too. -- The old `var` has some notable differences, they will be covered in the article . +- Neste artigo vamos usar variáveis `let` nos exemplos. +- Variáveis declaradas com `const` se comportam da mesma forma, então este artigo também é sobre `const`. +- O antigo `var` tem algumas diferenças notáveis, que serão cobertas no artigo . ``` -## Code blocks +## Blocos de código -If a variable is declared inside a code block `{...}`, it's only visible inside that block. +Se uma variável é declarada dentro de um bloco de código `{...}`, ela só é visível dentro desse bloco. -For example: +Por exemplo: ```js run { - // do some job with local variables that should not be seen outside + // faz algum trabalho com variáveis locais que não devem ser vistas fora - let message = "Hello"; // only visible in this block + let message = "Hello"; // só visível neste bloco alert(message); // Hello } -alert(message); // Error: message is not defined +alert(message); // Erro: message não está definido ``` -We can use this to isolate a piece of code that does its own task, with variables that only belong to it: +Podemos usar isso para isolar um trecho de código que faz sua própria tarefa, com variáveis que pertencem só a ele: ```js run { - // show message + // mostra mensagem let message = "Hello"; alert(message); } { - // show another message + // mostra outra mensagem let message = "Goodbye"; alert(message); } ``` -````smart header="There'd be an error without blocks" -Please note, without separate blocks there would be an error, if we use `let` with the existing variable name: +````smart header="Haveria um erro sem os blocos" +Observe que, sem blocos separados, haveria um erro, se usássemos `let` com um nome de variável já existente: ```js run -// show message +// mostra mensagem let message = "Hello"; alert(message); -// show another message +// mostra outra mensagem *!* -let message = "Goodbye"; // Error: variable already declared +let message = "Goodbye"; // Erro: variável já declarada */!* alert(message); ``` ```` -For `if`, `for`, `while` and so on, variables declared in `{...}` are also only visible inside: +Para `if`, `for`, `while` e assim por diante, variáveis declaradas em `{...}` também só são visíveis internamente: ```js run if (true) { @@ -78,38 +78,38 @@ if (true) { alert(phrase); // Hello! } -alert(phrase); // Error, no such variable! +alert(phrase); // Erro, essa variável não existe! ``` -Here, after `if` finishes, the `alert` below won't see the `phrase`, hence the error. +Aqui, depois que o `if` termina, o `alert` abaixo não vai ver a `phrase`, daí o erro. -That's great, as it allows us to create block-local variables, specific to an `if` branch. +Isso é ótimo, já que nos permite criar variáveis locais a um bloco, específicas a uma ramificação de `if`. -The similar thing holds true for `for` and `while` loops: +A mesma coisa vale para laços `for` e `while`: ```js run for (let i = 0; i < 3; i++) { - // the variable i is only visible inside this for - alert(i); // 0, then 1, then 2 + // a variável i só é visível dentro deste for + alert(i); // 0, depois 1, depois 2 } -alert(i); // Error, no such variable +alert(i); // Erro, essa variável não existe ``` -Visually, `let i` is outside of `{...}`. But the `for` construct is special here: the variable, declared inside it, is considered a part of the block. +Visualmente, `let i` está fora de `{...}`. Mas a construção `for` é especial aqui: a variável, declarada dentro dela, é considerada parte do bloco. -## Nested functions +## Funções aninhadas -A function is called "nested" when it is created inside another function. +Uma função é chamada de "aninhada" quando é criada dentro de outra função. -It is easily possible to do this with JavaScript. +Isso é facilmente possível com o JavaScript. -We can use it to organize our code, like this: +Podemos usar isso para organizar nosso código, assim: ```js function sayHiBye(firstName, lastName) { - // helper nested function to use below + // função aninhada auxiliar pra usar abaixo function getFullName() { return firstName + " " + lastName; } @@ -120,11 +120,11 @@ function sayHiBye(firstName, lastName) { } ``` -Here the *nested* function `getFullName()` is made for convenience. It can access the outer variables and so can return the full name. Nested functions are quite common in JavaScript. +Aqui a função *aninhada* `getFullName()` é feita por conveniência. Ela pode acessar as variáveis externas e, assim, consegue retornar o nome completo. Funções aninhadas são bem comuns no JavaScript. -What's much more interesting, a nested function can be returned: either as a property of a new object or as a result by itself. It can then be used somewhere else. No matter where, it still has access to the same outer variables. +O que é bem mais interessante, uma função aninhada pode ser retornada: seja como propriedade de um novo objeto, seja como resultado por si só. Ela pode então ser usada em outro lugar. Não importa onde, ela ainda tem acesso às mesmas variáveis externas. -Below, `makeCounter` creates the "counter" function that returns the next number on each invocation: +Abaixo, `makeCounter` cria a função "counter" que retorna o próximo número a cada chamada: ```js run function makeCounter() { @@ -142,87 +142,87 @@ alert( counter() ); // 1 alert( counter() ); // 2 ``` -Despite being simple, slightly modified variants of that code have practical uses, for instance, as a [random number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) to generate random values for automated tests. +Apesar de simples, variantes ligeiramente modificadas desse código têm usos práticos, por exemplo, como um [gerador de números pseudoaleatórios](https://pt.wikipedia.org/wiki/Gerador_de_n%C3%BAmeros_pseudoaleat%C3%B3rios) para gerar valores aleatórios em testes automatizados. -How does this work? If we create multiple counters, will they be independent? What's going on with the variables here? +Como isso funciona? Se criarmos vários contadores, eles vão ser independentes? O que está acontecendo com as variáveis aqui? -Understanding such things is great for the overall knowledge of JavaScript and beneficial for more complex scenarios. So let's go a bit in-depth. +Entender essas coisas é ótimo para o conhecimento geral do JavaScript e benéfico para cenários mais complexos. Então vamos nos aprofundar um pouco. -## Lexical Environment +## Ambiente Léxico -```warn header="Here be dragons!" -The in-depth technical explanation lies ahead. +```warn header="Aqui existem dragões!" +A explicação técnica aprofundada vem a seguir. -As far as I'd like to avoid low-level language details, any understanding without them would be lacking and incomplete, so get ready. +Por mais que eu gostaria de evitar detalhes de baixo nível da linguagem, qualquer entendimento sem eles ficaria incompleto e deficiente, então se prepare. ``` -For clarity, the explanation is split into multiple steps. +Para clareza, a explicação é dividida em várias etapas. -### Step 1. Variables +### Passo 1. Variáveis -In JavaScript, every running function, code block `{...}`, and the script as a whole have an internal (hidden) associated object known as the *Lexical Environment*. +No JavaScript, toda função em execução, bloco de código `{...}`, e o script como um todo têm um objeto interno (oculto) associado conhecido como *Ambiente Léxico*. -The Lexical Environment object consists of two parts: +O objeto Ambiente Léxico consiste em duas partes: -1. *Environment Record* -- an object that stores all local variables as its properties (and some other information like the value of `this`). -2. A reference to the *outer lexical environment*, the one associated with the outer code. +1. *Environment Record* -- um objeto que armazena todas as variáveis locais como suas propriedades (e algumas outras informações, como o valor de `this`). +2. Uma referência ao *ambiente léxico externo*, aquele associado ao código externo. -**A "variable" is just a property of the special internal object, `Environment Record`. "To get or change a variable" means "to get or change a property of that object".** +**Uma "variável" é só uma propriedade do objeto interno especial, `Environment Record`. "Obter ou mudar uma variável" significa "obter ou mudar uma propriedade desse objeto".** -In this simple code without functions, there is only one Lexical Environment: +Neste código simples, sem funções, existe apenas um Ambiente Léxico: -![lexical environment](lexical-environment-global.svg) +![ambiente léxico](lexical-environment-global.svg) -This is the so-called *global* Lexical Environment, associated with the whole script. +Esse é o chamado Ambiente Léxico *global*, associado ao script inteiro. -On the picture above, the rectangle means Environment Record (variable store) and the arrow means the outer reference. The global Lexical Environment has no outer reference, that's why the arrow points to `null`. +Na imagem acima, o retângulo representa o Environment Record (o armazenamento de variáveis) e a seta representa a referência externa. O Ambiente Léxico global não tem referência externa, por isso a seta aponta para `null`. -As the code starts executing and goes on, the Lexical Environment changes. +Conforme o código começa a executar e avança, o Ambiente Léxico muda. -Here's a little bit longer code: +Aqui está um código um pouco mais longo: -![lexical environment](closure-variable-phrase.svg) +![ambiente léxico](closure-variable-phrase.svg) -Rectangles on the right-hand side demonstrate how the global Lexical Environment changes during the execution: +Os retângulos do lado direito demonstram como o Ambiente Léxico global muda durante a execução: -1. When the script starts, the Lexical Environment is pre-populated with all declared variables. - - Initially, they are in the "Uninitialized" state. That's a special internal state, it means that the engine knows about the variable, but it cannot be referenced until it has been declared with `let`. It's almost the same as if the variable didn't exist. -2. Then `let phrase` definition appears. There's no assignment yet, so its value is `undefined`. We can use the variable from this point forward. -3. `phrase` is assigned a value. -4. `phrase` changes the value. +1. Quando o script começa, o Ambiente Léxico já vem pré-populado com todas as variáveis declaradas. + - Inicialmente, elas estão no estado "Não inicializado" (*Uninitialized*). Esse é um estado interno especial, significa que o motor sabe sobre a variável, mas ela não pode ser referenciada até ter sido declarada com `let`. É quase como se a variável não existisse. +2. Então a definição `let phrase` aparece. Ainda não há atribuição, então seu valor é `undefined`. Podemos usar a variável a partir desse ponto em diante. +3. `phrase` recebe um valor atribuído. +4. `phrase` muda de valor. -Everything looks simple for now, right? +Por enquanto tudo parece simples, certo? -- A variable is a property of a special internal object, associated with the currently executing block/function/script. -- Working with variables is actually working with the properties of that object. +- Uma variável é uma propriedade de um objeto interno especial, associado ao bloco/função/script que está sendo executado no momento. +- Trabalhar com variáveis, na verdade, é trabalhar com as propriedades desse objeto. -```smart header="Lexical Environment is a specification object" -"Lexical Environment" is a specification object: it only exists "theoretically" in the [language specification](https://tc39.es/ecma262/#sec-lexical-environments) to describe how things work. We can't get this object in our code and manipulate it directly. +```smart header="Ambiente Léxico é um objeto de especificação" +"Ambiente Léxico" é um objeto de especificação: ele só existe "teoricamente" na [especificação da linguagem](https://tc39.es/ecma262/#sec-lexical-environments) para descrever como as coisas funcionam. Não conseguimos obter esse objeto no nosso código e manipulá-lo diretamente. -JavaScript engines also may optimize it, discard variables that are unused to save memory and perform other internal tricks, as long as the visible behavior remains as described. +Os motores do JavaScript também podem otimizá-lo, descartar variáveis que não são usadas para economizar memória e realizar outros truques internos, desde que o comportamento visível continue sendo o descrito. ``` -### Step 2. Function Declarations +### Passo 2. Declarações de Função -A function is also a value, like a variable. +Uma função também é um valor, assim como uma variável. -**The difference is that a Function Declaration is instantly fully initialized.** +**A diferença é que uma Declaração de Função é totalmente inicializada instantaneamente.** -When a Lexical Environment is created, a Function Declaration immediately becomes a ready-to-use function (unlike `let`, that is unusable till the declaration). +Quando um Ambiente Léxico é criado, uma Declaração de Função se torna imediatamente uma função pronta pra uso (diferente de `let`, que fica inutilizável até a declaração). -That's why we can use a function, declared as Function Declaration, even before the declaration itself. +É por isso que podemos usar uma função, declarada como Declaração de Função, até mesmo antes da própria declaração. -For example, here's the initial state of the global Lexical Environment when we add a function: +Por exemplo, aqui está o estado inicial do Ambiente Léxico global quando adicionamos uma função: ![](closure-function-declaration.svg) -Naturally, this behavior only applies to Function Declarations, not Function Expressions where we assign a function to a variable, such as `let say = function(name)...`. +Naturalmente, esse comportamento só se aplica a Declarações de Função, não a Expressões de Função, onde atribuímos uma função a uma variável, como `let say = function(name)...`. -### Step 3. Inner and outer Lexical Environment +### Passo 3. Ambiente Léxico interno e externo -When a function runs, at the beginning of the call, a new Lexical Environment is created automatically to store local variables and parameters of the call. +Quando uma função roda, no início da chamada, um novo Ambiente Léxico é criado automaticamente para armazenar as variáveis locais e os parâmetros da chamada. -For instance, for `say("John")`, it looks like this (the execution is at the line, labelled with an arrow): +Por exemplo, para `say("John")`, fica assim (a execução está na linha marcada com uma seta):