mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-28 21:00:56 +08:00
feat(curriculum): Add interactive examples to closures lesson (#63380)
This commit is contained in:
parent
a53407d752
commit
b771044e9f
@ -5,12 +5,14 @@ challengeType: 19
|
||||
dashedName: what-are-closures-and-how-do-they-work
|
||||
---
|
||||
|
||||
# --description--
|
||||
# --interactive--
|
||||
|
||||
Closures are one of the most powerful and often misunderstood features in JavaScript. At its core, a closure is a function that has access to variables in its outer enclosing lexical scope, even after the outer function has returned. This might sound complex but it's a fundamental concept that enables many advanced programming patterns in JavaScript.
|
||||
|
||||
To understand closures, let's start with an example:
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
function outerFunction(x) {
|
||||
let y = 10;
|
||||
@ -21,15 +23,19 @@ function outerFunction(x) {
|
||||
}
|
||||
|
||||
let closure = outerFunction(5);
|
||||
closure(); // Output: 15
|
||||
console.log(closure()); // 15
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
In this example, `outerFunction` takes a parameter `x` and defines a local variable `y`. It then defines an `innerFunction` that uses both `x` and `y`. Finally it returns `innerFunction`. When we call `outerFunction(5)` it returns `innerFunction` which we assign to the variable `closure`. When we later call `closure()` it still has access to `x` and `y` from `outerFunction` even though `outerFunction` has already finished executing. This is the essence of a closure.
|
||||
|
||||
The inner function maintains a reference to its outer lexical environment, preserving access to the variables in that environment even after the outer function has completed.
|
||||
|
||||
Closures are particularly useful for creating private variables and functions. Consider this example:
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
function createCounter() {
|
||||
let count = 0;
|
||||
@ -40,14 +46,18 @@ function createCounter() {
|
||||
}
|
||||
|
||||
let counter = createCounter();
|
||||
console.log(counter()); // Output: 1
|
||||
console.log(counter()); // Output: 2
|
||||
console.log(counter()); // 1
|
||||
console.log(counter()); // 2
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
In this case, `createCounter` returns a function that increments and returns a `count` variable. The `count` variable is not directly accessible from outside `createCounter`, but the returned function (our closure) has access to it. Each time we call `counter()`, it increments and returns the `count`.
|
||||
|
||||
Closures can also capture multiple variables from their outer scope. For example:
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
function multiply(x) {
|
||||
return function (y) {
|
||||
@ -56,13 +66,17 @@ function multiply(x) {
|
||||
}
|
||||
|
||||
let double = multiply(2);
|
||||
console.log(double(5)); // Output: 10
|
||||
console.log(double(5)); // 10
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Here the inner function captures the `x` parameter from `multiply`. When we create `double` by calling `multiply(2)` it returns a function that always multiplies its argument by `2`.
|
||||
|
||||
One important thing to note about closures is that they capture variables, by reference not by value. This means if the value of a captured variable changes, the closure will see the new value. For example:
|
||||
|
||||
:::interactive_editor
|
||||
|
||||
```js
|
||||
function createIncrementer() {
|
||||
let count = 0;
|
||||
@ -73,10 +87,12 @@ function createIncrementer() {
|
||||
}
|
||||
|
||||
let increment = createIncrementer();
|
||||
increment(); // Output: 1
|
||||
increment(); // Output: 2
|
||||
increment(); // 1
|
||||
increment(); // 2
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Each time we call `increment` its working with the same `count` variable, not a copy of it's initial value. Closures are a powerful tool in JavaScript. as you continue to work with JavaScript you'll find that understanding and using closures effectively can greatly enhance your ability to write clean, efficient and powerful code.
|
||||
|
||||
# --questions--
|
||||
|
||||
Loading…
Reference in New Issue
Block a user