diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 9bd016c9ed..43d8c0d16f 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -8,7 +8,7 @@ ## 변수(variable) -[변수(variable)](https://en.wikipedia.org/wiki/Variable_(computer_science)) 는 데이터를 위한 "이름을 붙인 저장소" 입니다. 우리는 상품, 방문객 등의 데이터를 저장하기 위해 변수를 사용할 수 있습니다. +[변수(variable)](https://en.wikipedia.org/wiki/Variable_(computer_science)) 는 데이터를 위한 "이름을 붙인 저장소" 입니다. 상품, 방문객 등의 데이터를 저장하기 위해 변수를 사용할 수 있습니다. 자바스크립트에선 변수를 생성할 때 `let` 키워드를 사용합니다. diff --git a/1-js/04-object-basics/02-garbage-collection/article.md b/1-js/04-object-basics/02-garbage-collection/article.md index bac630b4f1..ab4506b7a5 100644 --- a/1-js/04-object-basics/02-garbage-collection/article.md +++ b/1-js/04-object-basics/02-garbage-collection/article.md @@ -14,8 +14,8 @@ 예를 들어: - - 현재 함수의 지역 변수와 매개 변수 - - 중첩된 함수 호출로 실행된 경우 현재 스코프 체인에 있는 변수와 매개 변수 + - 현재 함수의 지역 변수와 매개변수 + - 중첩된 함수 호출로 실행된 경우 현재 스코프 체인에 있는 변수와 매개변수 - 전역 변수 - (내부적인 다른 값들도 존재합니다.) diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index db4f1536b4..985e2e4567 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -32,13 +32,13 @@ user.sayHi = function() { user.sayHi(); // Hello! ``` -여기서 우리는 함수를 만들기 위해서 Function 표현을 사용했습니다. 그리고 객체의 `user.sayHi` 속성에 이것을 할당해 줬습니다. +여기서 함수를 만들기 위해서 Function 표현을 사용했습니다. 그리고 객체의 `user.sayHi` 속성에 이것을 할당해 줬습니다. 그리고서 이것을 호출할 수 있죠. 이제는 user가 말할 수 있습니다! 객체의 속성인 함수를 *메서드*라고 부릅니다. -즉, 여기서 우리는 `user`안에 `sayHi`메서드를 가진 것이죠. +즉, 여기서 `user`안에 `sayHi`메서드를 가진 것이죠. 물론, 미리 선언된 함수를 메서드로 사용할 수 있습니다. 이렇게요: diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md index cabc13290a..b84edde770 100644 --- a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md +++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Sum all numbers till the given one +# 주어진 숫자까지 모든 숫자를 합해보세요. -Write a function `sumTo(n)` that calculates the sum of numbers `1 + 2 + ... + n`. +숫자`1 + 2 + ... + n`의 합을 계산하는 함수`sumTo (n)`을 작성하세요. -For instance: +예를들면 ```js no-beautify sumTo(1) = 1 @@ -17,13 +17,13 @@ sumTo(4) = 4 + 3 + 2 + 1 = 10 sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050 ``` -Make 3 solution variants: +3 가지 솔루션 변형 만들기 -1. Using a for loop. -2. Using a recursion, cause `sumTo(n) = n + sumTo(n-1)` for `n > 1`. -3. Using the [arithmetic progression](https://en.wikipedia.org/wiki/Arithmetic_progression) formula. +1. for 반복문 사용. +2. 재귀를 사용하면`n> 1`에 대해`sumTo (n) = n + sumTo (n-1)`이 됩니다. +3. [산술 진행](https://en.wikipedia.org/wiki/Arithmetic_progression) 공식사용. -An example of the result: +결과의 예 ```js function sumTo(n) { /*... your code ... */ } @@ -31,6 +31,6 @@ function sumTo(n) { /*... your code ... */ } alert( sumTo(100) ); // 5050 ``` -P.S. Which solution variant is the fastest? The slowest? Why? +P.S. 어떤 솔루션 변형이 가장 빠릅니까? 가장 느린 것은 어떤 것 입니까? 왜 그럴까요? -P.P.S. Can we use recursion to count `sumTo(100000)`? +P.P.S. 재귀를 사용하여 `sumTo (100000)`를 계산할 수 있습니까? diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md index d2aef2d903..41cdff8410 100644 --- a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md +++ b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md @@ -1,18 +1,17 @@ importance: 4 --- +# 계승 계산 -# Calculate factorial +자연수의 [계승](https://en.wikipedia.org/wiki/Factorial) (factorialial)은 숫자에 "1"을 곱한 다음 숫자를 2 "등으로 곱한 다음 1까지 계속됩니다. 'n'의 계승은`n! '으로 표시됩니다. -The [factorial](https://en.wikipedia.org/wiki/Factorial) of a natural number is a number multiplied by `"number minus one"`, then by `"number minus two"`, and so on till `1`. The factorial of `n` is denoted as `n!` - -We can write a definition of factorial like this: +계승의 정의는 다음과 같이 쓸 수 있습니다 ```js n! = n * (n - 1) * (n - 2) * ...*1 ``` -Values of factorials for different `n`: +'n'에 대한 계승의 다른 값 ```js 1! = 1 @@ -22,10 +21,10 @@ Values of factorials for different `n`: 5! = 5 * 4 * 3 * 2 * 1 = 120 ``` -The task is to write a function `factorial(n)` that calculates `n!` using recursive calls. +재귀인 방법을 사용하여`n! '을 계산하는`factorial (n)`함수를 작성하세요. ```js alert( factorial(5) ); // 120 ``` -P.S. Hint: `n!` can be written as `n * (n-1)!` For instance: `3! = 3*2! = 3*2*1! = 6` +P.S. 힌트 :`n!`은`n * (n-1)! '로 쓸 수 있습니다! 예를 들면`3! = 3 * 2! = 3 * 2 * 1! = 6` diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md index 3cdadd219b..c8f1fa423e 100644 --- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md +++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md @@ -1,18 +1,18 @@ importance: 5 --- +# 피보나치 수 -# Fibonacci numbers +피보나치 수는 다음과 같은 공식을 가집니다 [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) +Fn = Fn-1 + Fn-2. 즉, 다음 숫자는 앞의 두 숫자의 합계입니다. -The sequence of [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) has the formula Fn = Fn-1 + Fn-2. In other words, the next number is a sum of the two preceding ones. +처음 두 숫자는`1`,`2 (1 + 1)`,`3 (1 + 2)`,`5 (2 + 3)`등등입니다 :`1, 1, 2, 3, 5 , 8, 13, 21 ...`. -First two numbers are `1`, then `2(1+1)`, then `3(1+2)`, `5(2+3)` and so on: `1, 1, 2, 3, 5, 8, 13, 21...`. +피보나치 수는 [황금 비율](https://en.wikipedia.org/wiki/Golden_ratio)과 우리 주변의 많은 자연 현상과 관련이 있습니다. -Fibonacci numbers are related to the [Golden ratio](https://en.wikipedia.org/wiki/Golden_ratio) and many natural phenomena around us. +`n 번째 '피보나치 수를 반환하는 함수`fib (n)'을 작성하세요. -Write a function `fib(n)` that returns the `n-th` Fibonacci number. - -An example of work: +예를 들면 ```js function fib(n) { /* your code */ } @@ -22,4 +22,4 @@ alert(fib(7)); // 13 alert(fib(77)); // 5527939700884757 ``` -P.S. The function should be fast. The call to `fib(77)` should take no more than a fraction of a second. +P.S. 이 기능은 빠릅니다. `fib (77)`에 대한 호출은 1 초도 걸리지 않습니다. diff --git a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md index 1076b952af..4051f5d4b2 100644 --- a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md +++ b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md @@ -1,10 +1,9 @@ importance: 5 --- +# 단일 연결 리스트 출력하기 -# Output a single-linked list - -Let's say we have a single-linked list (as described in the chapter ): +단일 연결 리스트가 있다고 가정 해 봅니다 (): ```js let list = { @@ -22,8 +21,8 @@ let list = { }; ``` -Write a function `printList(list)` that outputs list items one-by-one. +목록 항목을 하나씩 출력하는`printList (list)`함수를 작성해보세요. -Make two variants of the solution: using a loop and using recursion. +반목문을 사용하고 재귀적인 방법을 사용해서 두 가지로 접근해봅니다. -What's better: with recursion or without it? +어떤 게 더 좋은 코드인가요? 재귀가 있는 것인가요? 없는 것인가요? diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md index 81b1f3e33a..d132c9f592 100644 --- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md +++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md @@ -1,9 +1,8 @@ importance: 5 --- +# 단일 연결 리스트를 역순으로 출력하기 -# Output a single-linked list in the reverse order +이전 작업의 단일 연결 목록을 역순으로 출력합니다. -Output a single-linked list from the previous task in the reverse order. - -Make two solutions: using a loop and using a recursion. +반목 문을 사용하는 것과 재귀적인 방법을 사용하는 것 두 가지를 만들어보세요. diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md index 036ae7f516..d477ce1a89 100644 --- a/1-js/06-advanced-functions/01-recursion/article.md +++ b/1-js/06-advanced-functions/01-recursion/article.md @@ -1,18 +1,18 @@ -# Recursion and stack +# 재귀와 스택 -Let's return to functions and study them more in-depth. +함수에 대해 조금 더 깊이 공부해보죠. -Our first topic will be *recursion*. +첫 번째 주제는 *재귀* 입니다. -If you are not new to programming, then it is probably familiar and you could skip this chapter. +새롭게 프로그램을 배우는게 아니고, 재귀에 익숙하다면 이 챕터는 건너뛰어도 좋습니다. -Recursion is a programming pattern that is useful in situations when a task can be naturally split into several tasks of the same kind, but simpler. Or when a task can be simplified into an easy action plus a simpler variant of the same task. Or, as we'll see soon, to deal with certain data structures. +재귀는 프로그래밍 패턴 중에 하나이며 작업이 여러 가지 비슷한 과정으로 나누어질 수 있을 떄 유용합니다. +더 간단하죠. 작업이 더 쉬운 방법과 동일한 작업이 단순화 시킬 수 있을 때. 또는, 특정 데이터 구조로 다룰 수 있을때 사용합니다. +함수가 진행될 때 프로세스에서 다른 많은 함수를 호출할 수 있습니다. 이때 함수가 *자기 자신* 을 호출할 때, 그것을 *재귀* 라고 부릅니다. -When a function solves a task, in the process it can call many other functions. A partial case of this is when a function calls *itself*. That's called *recursion*. +## 두 가지 사고 방식 -## Two ways of thinking - -For something simple to start with -- let's write a function `pow(x, n)` that raises `x` to a natural power of `n`. In other words, multiplies `x` by itself `n` times. +`pow` (x, n) 함수를 작성하여 `x`를 `n`의 제곱을 하는 것부터 시작해 보겠습니다. `x` 를 `n` 배 곱합니다. ```js pow(2, 2) = 4 @@ -20,9 +20,9 @@ pow(2, 3) = 8 pow(2, 4) = 16 ``` -There are two ways to implement it. +이것을 구현하는데는 두 가지 방법이 있습니다. -1. Iterative thinking: the `for` loop: +1. 반복적인 방법: `for` 루프: ```js run function pow(x, n) { @@ -39,7 +39,7 @@ There are two ways to implement it. alert( pow(2, 3) ); // 8 ``` -2. Recursive thinking: simplify the task and call self: +2. 재귀적인 방법: 작업을 단순화하고 스스로를 부르기: ```js run function pow(x, n) { @@ -53,39 +53,41 @@ There are two ways to implement it. alert( pow(2, 3) ); // 8 ``` -Please note how the recursive variant is fundamentally different. +재귀적 방법이 근본적으로 어떻게 다른지 유의하세요. -When `pow(x, n)` is called, the execution splits into two branches: +`pow (x, n)`이 호출되면, 실행은 두 개의 분기로 나누어집니다: ```js if n==1 = x / pow(x, n) = - \ + \ else = x * pow(x, n - 1) ``` -1. If `n == 1`, then everything is trivial. It is called *the base* of recursion, because it immediately produces the obvious result: `pow(x, 1)` equals `x`. -2. Otherwise, we can represent `pow(x, n)` as `x * pow(x, n - 1)`. In maths, one would write xn = x * xn-1. This is called *a recursive step*: we transform the task into a simpler action (multiplication by `x`) and a simpler call of the same task (`pow` with lower `n`). Next steps simplify it further and further until `n` reaches `1`. +1. 만약 `n == 1` 이면, 모든 것이 무시된다. 이것을 *재귀의 base* 라고 부릅니다, 왜냐하면 `pow(x, 1)` 가 `x` 와 같다는 것을 즉시 보여주기 때문이죠. +2. 그렇지 않으면` pow(x, n)`를`x * pow(x, n - 1)`로 표현할 수 있습니다. 수학에서는, 이렇게 쓸 수 있습니다. xn = x * xn-1. +이것은 *재귀적 단계* 라고 부릅니다: 작업을 보다 단순하게 (`x`에 의한 곱셈)으로 바꾸고 더 간단한 동일한 작업이 호출됩니다. (더 낮은 `n` 을 가진 `pow`). +다음 단계는 `n`이 `1`이 될 때까지 계속 간소화합니다. -We can also say that `pow` *recursively calls itself* till `n == 1`. +이때 `pow` 가 `n == 1`까지 재귀적으로 호출되었다고 할 수 있습니다. ![recursive diagram of pow](recursion-pow.png) -For example, to calculate `pow(2, 4)` the recursive variant does these steps: +예를 들어 `pow (2, 4)`를 계산하기 위해서 재귀적 변수들은 다음 단계들을 수행합니다: 1. `pow(2, 4) = 2 * pow(2, 3)` 2. `pow(2, 3) = 2 * pow(2, 2)` 3. `pow(2, 2) = 2 * pow(2, 1)` 4. `pow(2, 1) = 2` -So, the recursion reduces a function call to a simpler one, and then -- to even more simpler, and so on, until the result becomes obvious. +재귀는 함수 호출을 단순한 함수 호출로 축소한 다음 결과가 끝날때까지 간단하게 처리됩니다. -````smart header="Recursion is usually shorter" -A recursive solution is usually shorter than an iterative one. +````smart header="재귀는 보통 짧습니다" +재귀적 방법은 대개 반복적인 방법(loop) 보다 짧습니다. -Here we can rewrite the same using the ternary `?` operator instead of `if` to make `pow(x, n)` more terse and still very readable: +여기서 `pow (x, n)` 을 `if` 대신에 `?` 연산자를 사용하면 같은 것을 더 간결하면서도 매우 읽기 쉽도록 다시 쓸 수 있습니다: ```js run function pow(x, n) { @@ -94,36 +96,37 @@ function pow(x, n) { ``` ```` -The maximal number of nested calls (including the first one) is called *recursion depth*. In our case, it will be exactly `n`. +중첩된 호출 (첫 번째 호출 포함)의 최대 개수는 *재귀 깊이* 라고 합니다. 정확히는 `n`. -The maximal recursion depth is limited by JavaScript engine. We can make sure about 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases. +최대 재귀 깊이는 자바스크립트 엔진에 의해 제한됩니다. 약 10000까지를 만들 수 있습니다. 일부 엔진은 더 많은 것을 허용하지만, +대다수 엔진의 경우 100000 이상은 아마도 한계일 것입니다. 이 문제를 완화하는 데 도움이 되는 자동 최적화가 있지만 ( "tail calls optimizations"), 아직 모든 곳에서 지원되지 않고 일부의 경우에만 작동합니다. -That limits the application of recursion, but it still remains very wide. There are many tasks where recursive way of thinking gives simpler code, easier to maintain. +재귀를 사용하는데 이러한 제약은 있지만, 재귀는 여전히 매우 광범위하게 사용됩니다. 재귀적 사고방식이 많은 작업에서 코드를 간결하게하고 유지 보수하기 쉽게 만듭니다. -## The execution stack +## 실행 스택 -Now let's examine how recursive calls work. For that we'll look under the hood of functions. +어떻게 재귀적인 호출이 작동하는지 살펴보겠습니다. 함수의 보이지않는 부분을 살펴볼 필요가 있습니다. -The information about a function run is stored in its *execution context*. +함수 실행에 대한 정보는 해당하는 *실행 컨텍스트* 에 저장됩니다. -The [execution context](https://tc39.github.io/ecma262/#sec-execution-contexts) is an internal data structure that contains details about the execution of a function: where the control flow is now, the current variables, the value of `this` (we don't use it here) and few other internal details. +[실행 컨텍스트](https://tc39.github.io/ecma262/#sec-execution-contexts) 는 함수의 실행에 대한 세부 사항을 포함하는 내부 데이터 구조: 제어 흐름이 현재의 변수, `this`의 값 (여기서는 사용하지 않음) 및 다른 몇 가지 내부 세부 사항 입니다. -One function call has exactly one execution context associated with it. +한개의 함수 호출에는 정확히 한개의 실행 컨텍스트가 연결되어 있습니다. -When a function makes a nested call, the following happens: +함수가 중첩 호출을 하면 다음과 같은 일이 발생합니다: -- The current function is paused. -- The execution context associated with it is remembered in a special data structure called *execution context stack*. -- The nested call executes. -- After it ends, the old execution context is retrieved from the stack, and the outer function is resumed from where it stopped. +- 현재 함수가 중지된다. +- 이와 관련된 실행 컨텍스트는 *실행 컨텍스트 스택* 이라는 특수 데이터 구조로 기억된다. +- 중첩된 호출이 실행된다. +- 그것이 끝난 후 스택에서 이전 실행 컨텍스트를 검색하고 중지된 위치에서 외부 함수를 다시 시작한다. -Let's see what happens during the `pow(2, 3)` call. +이것이 `pow (2, 3)` 호출 중에 어떻게 진행되는지 살펴보죠. ### pow(2, 3) -In the beginning of the call `pow(2, 3)` the execution context will store variables: `x = 2, n = 3`, the execution flow is at line `1` of the function. +`pow (2, 3)` 호출의 시작 부분에서 실행 컨텍스트는 변수를 저장합니다 :`x = 2, n = 3`, 실행 흐름은 함수의 `1` 라인에 있습니다. -We can sketch it as: +다음과 같이 그려볼 수 있습니다 :
  • @@ -132,7 +135,7 @@ We can sketch it as:
-That's when the function starts to execute. The condition `n == 1` is false, so the flow continues into the second branch of `if`: +이때 함수가 실행되기 시작합니다. `n == 1` 조건은 거짓이므로, 흐름은 `if`의 두 번째 분기로 계속됩니다 : ```js run function pow(x, n) { @@ -148,8 +151,7 @@ function pow(x, n) { alert( pow(2, 3) ); ``` - -The variables are same, but the line changes, so the context is now: +변수는 동일하지만, 행이 변경되므로 컨텍스트는 다음과 같습니다.
  • @@ -158,19 +160,19 @@ The variables are same, but the line changes, so the context is now:
-To calculate `x * pow(x, n - 1)`, we need to make a subcall of `pow` with new arguments `pow(2, 2)`. +`x * pow (x, n - 1)`을 계산하려면, 새로운 인수 `pow (2, 2) `로 `pow`의 하위 호출을 만들어야 합니다. ### pow(2, 2) -To do a nested call, JavaScript remembers the current execution context in the *execution context stack*. +중첩 호출을 수행하기 위해 자바스크립트는 *실행 컨텍스트 스택* 에서 현재 실행 컨텍스트를 기억합니다. -Here we call the same function `pow`, but it absolutely doesn't matter. The process is the same for all functions: +여기에서 동일한 함수` pow`를 호출하지만, 크게 중요하지 않습니다. 프로세스는 모든 기능에 대해 동일하게 작동합니다. -1. The current context is "remembered" on top of the stack. -2. The new context is created for the subcall. -3. When the subcall is finished -- the previous context is popped from the stack, and its execution continues. +1. 현재 컨텍스트가 스택 제일 윗단계에 "기억" 된다. +2. 새로운 A 텍스트가 하위 호출용으로 작성된다. +3. 하위 호출이 완료되면 이전 컨텍스트가 스택에서 추출 되고 실행이 계속된다. -Here's the context stack when we entered the subcall `pow(2, 2)`: +하위 호출 `pow (2, 2)`은 컨텍스트 스택에 들어있습니다
  • @@ -183,15 +185,15 @@ Here's the context stack when we entered the subcall `pow(2, 2)`:
-The new current execution context is on top (and bold), and previous remembered contexts are below. +새로운 현재 실행 컨텍스트가 맨 위 (굵은 체)에 있으며 이전에 기억된 컨텍스트가 아래에 있습니다. -When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped. Here in the picture we use the word "line", but of course it's more precise. +하위 호출을 마치면 이전 컨텍스트를 다시 시작하기 쉬워집니다. 변수와 중지된 코드의 정확한 위치를 모두 유지하기 때문이죠. 더 정확히는 해당 코드의 라인(line)으로 표기된 부분입니다. ### pow(2, 1) -The process repeats: a new subcall is made at line `5`, now with arguments `x=2`, `n=1`. +프로세스는 다음과 같이 반복됩니다 : 새로운 하위 호출이 라인 `5`에서 만들어졌을때, ` x = 2`,`n = 1`을 인수로 사용합니다. -A new execution context is created, the previous one is pushed on top of the stack: +새로운 실행 컨텍스트가 만들어지고, 이전 실행 컨텍스트가 스택 제일 위에 올려지게 됩니다.
  • @@ -208,11 +210,11 @@ A new execution context is created, the previous one is pushed on top of the sta
-There are 2 old contexts now and 1 currently running for `pow(2, 1)`. +현재 2개의 이전 컨텍스트가 있고` pow (2, 1)`로 현재 실행 중인 컨텍스트가 1 개 있습니다. ### The exit -During the execution of `pow(2, 1)`, unlike before, the condition `n == 1` is truthy, so the first branch of `if` works: +`pow (2, 1)`을 실행하는 동안 이전과 달리 `n == 1` 조건은 true 이므로 `if`의 첫 번째 분기가 작동합니다 : ```js function pow(x, n) { @@ -226,9 +228,9 @@ function pow(x, n) { } ``` -There are no more nested calls, so the function finishes, returning `2`. +더 중첩된 호출이 없으므로 함수가 완료되고 `2`가 반환됩니다. -As the function finishes, its execution context is not needed anymore, so it's removed from the memory. The previous one is restored off the top of the stack: +함수가 끝나면 실행 컨텍스트가 더 필요하지 않으므로 메모리에서 제거됩니다. 이전 스택은 스택 맨 위에서 복원됩니다.
    @@ -242,9 +244,9 @@ As the function finishes, its execution context is not needed anymore, so it's r
-The execution of `pow(2, 2)` is resumed. It has the result of the subcall `pow(2, 1)`, so it also can finish the evaluation of `x * pow(x, n - 1)`, returning `4`. +`pow (2, 2)`의 실행이 재개됩니다. 서브 콜 `pow (2, 1)`의 결과를 가지므로, `x * pow (x, n - 1)`를 끝내고, `4`를 반환합니다. -Then the previous context is restored: +그 다음 이전 컨텍스트가 복원됩니다.
  • @@ -253,15 +255,15 @@ Then the previous context is restored:
-When it finishes, we have a result of `pow(2, 3) = 8`. +끝나면 `pow (2, 3) = 8`의 결과를 얻습니다. -The recursion depth in this case was: **3**. +이 경우 재귀 깊이는 **3** 입니다. -As we can see from the illustrations above, recursion depth equals the maximal number of context in the stack. +위의 그림에서 알 수 있듯이 재귀 깊이는 스택의 최대 컨텍스트 수와 같습니다. -Note the memory requirements. Contexts take memory. In our case, raising to the power of `n` actually requires the memory for `n` contexts, for all lower values of `n`. +이때 메모리를 요구한다는 것에 주의해야 합니다. 컨텍스트는 메모리를 사용합니다. `n`을 제곱하려면` n`의 모든 낮은 값에 대해 실제로 `n`개의 컨텍스트를 위한 메모리가 필요합니다. -A loop-based algorithm is more memory-saving: +반복 기반 알고리즘은 메모리를 많이 절약합니다. ```js function pow(x, n) { @@ -275,19 +277,19 @@ function pow(x, n) { } ``` -The iterative `pow` uses a single context changing `i` and `result` in the process. Its memory requirements are small, fixed and do not depend on `n`. +반복적인 `pow`는 단일 컨텍스트를 사용하여 프로세스에서` i`과`result`를 변경합니다. 메모리 요구 사항은 작고 고정되어 있으며 `n`과는 상관없습니다. -**Any recursion can be rewritten as a loop. The loop variant usually can be made more effective.** +**모든 재귀적인 방법은 반복적인 방법(loop)으로 다시 작성할 수 있습니다. 반복적인 방법으로의 변형은 일반적으로 효과적일 수 있습니다.** -...But sometimes the rewrite is non-trivial, especially when function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts. +...하지만 때로는 다시 쓰는 것이 중요하지 않습니다. 특히 함수가 조건에 따라 다른 재귀적인 하위 호출을 사용하고 결과를 병합하거나 분기가 더 복잡한 경우에 그렇습니다. 이런 최적화는 불필요하므로 노력을 기울일 필요는 없습니다. -Recursion can give a shorter code, easier to understand and support. Optimizations are not required in every place, mostly we need a good code, that's why it's used. +재귀는 더 적은 코드로 작성할 수 있고 이해하기 쉽지만 모든 곳에서 최적화가 필요하지는 않으며 대부분 좋은 코드가 필요할때 재귀를 사용합니다. -## Recursive traversals +## 재귀적인 순회 -Another great application of the recursion is a recursive traversal. +재귀의 또 다른 훌륭한 점은 재귀적 순회입니다. -Imagine, we have a company. The staff structure can be presented as an object: +예를들면 회사가 있다고 할때, 직원 구조는 객체로 표현될 수 있습니다. ```js let company = { @@ -316,30 +318,32 @@ let company = { }; ``` -In other words, a company has departments. +한 회사에 부서가 있습니다. -- A department may have an array of staff. For instance, `sales` department has 2 employees: John and Alice. -- Or a department may split into subdepartments, like `development` has two branches: `sites` and `internals`. Each of them has the own staff. -- It is also possible that when a subdepartment grows, it divides into subsubdepartments (or teams). +- 부서에는 여러 명의 직원이 있을 수 있습니다. 예를 들어 `sales` 부서에는 John과 Alice라는 2명의 직원이 있습니다. +- 부서는 하위 개발 부서로 나눌 수 있습니다. `development` 부서에는 `sites`와 `internals`가 두 개가 있습니다. 각각에든 직원이 있습니다. +- 하위 부서가 커지면 하위 부서 (또는 팀)으로 나눌 수도 있습니다. - For instance, the `sites` department in the future may be split into teams for `siteA` and `siteB`. And they, potentially, can split even more. That's not on the picture, just something to have in mind. + 예를 들어 미래의 `sites` 부서는 `sited부서는` `siteA` 와 `siteB` 에 대해 팀으로 분리될 수 있고, 잠재적으로 더 많이 나누어질 수 있습니다. 여기서는 일단 가능성만 생각해보죠. -Now let's say we want a function to get the sum of all salaries. How can we do that? +이제 모든 급여의 합계를 구하는 함수가 필요하다고 한다면. 어떻게 할 수 있을까요? -An iterative approach is not easy, because the structure is not simple. The first idea may be to make a `for` loop over `company` with nested subloop over 1st level departments. But then we need more nested subloops to iterate over the staff in 2nd level departments like `sites`. ...And then another subloop inside those for 3rd level departments that might appear in the future? Should we stop on level 3 or make 4 levels of loops? If we put 3-4 nested subloops in the code to traverse a single object, it becomes rather ugly. +구조가 단순하지 않기 때문에 반복 접근법은 쉽지 않습니다. 첫 번째 아이디어는 1단계 부서 이상의 중첩 된 하위 반복으로 `company`에 대해 `for` 반복문을 만드는 것일 수 있지만 +`sites`와 같은 2단계 부서의 직원을 반복하기 위해 더 많이 중첩 된 하위 반복문이 필요합니다. ... 그리고 다음 단계에서 3단계 부서의 하위 반복문이 필요할 것입니다. +3단계 에서 멈추거나 4단계의 반복문을 만들어야 할까요? 코드에 3-4 중첩 된 하위 반복문을 사용하여 단일 객체를 탐색하면 오히려 안 좋은 코드가 됩니다. -Let's try recursion. +그럼, 재귀를 사용해 보죠. -As we can see, when our function gets a department to sum, there are two possible cases: +함수가 합계를 계산할 때처럼, 두 가지를 생각해 볼 수 있습니다. -1. Either it's a "simple" department with an *array of people* -- then we can sum the salaries in a simple loop. -2. Or it's *an object with `N` subdepartments* -- then we can make `N` recursive calls to get the sum for each of the subdeps and combine the results. +1. *사람들의 배열* 을 가진 "단순한" 부서 - 간단한 반복문으로 합계를 구할 수 있습니다. +2. *N 개의 작은 부서가 있는 객체* - 각각의 하위 부서의 합계를 얻기 위해 `N` 번의 회귀 호출을 하고 결과를 합산 합니다. -The (1) is the base of recursion, the trivial case. +(1)은 재귀의 base 이며 일반적인 방법입니다. -The (2) is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). +(2)는 재귀적인 방법입니다. 복잡한 작업은 작은 부서 단위의 작은 작업으로 나누어집니다. 그 다음 차례로 다시 나뉘어 지지만 결국 (1) 로 끝납니다. -The algorithm is probably even easier to read from the code: +이 알고리즘은 코드에서 읽기 쉽습니다. ```js run @@ -369,62 +373,62 @@ function sumSalaries(department) { alert(sumSalaries(company)); // 6700 ``` -The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting. +코드가 짧고 이해하기 쉽다면, 이것이 재귀의 강력함 입니다. 또한 중첩된 모든 하위구문에서도 작동합니다. -Here's the diagram of calls: +호출 단계를 보여주는 다이어그램은 다음과 같습니다. ![recursive salaries](recursive-salaries.png) -We can easily see the principle: for an object `{...}` subcalls are made, while arrays `[...]` are the "leaves" of the recursion tree, they give immediate result. +객체`{...}`에 대해 하위 호출이 만들어지고, 배열 `[...]`은 재귀 단계의 "작은 단계" 이지만 즉시 결과를 보여줍니다. -Note that the code uses smart features that we've covered before: +이 코드는 이전에 다뤘던 스마트 기능도 사용합니다. -- Method `arr.reduce` explained in the chapter to get the sum of the array. -- Loop `for(val of Object.values(obj))` to iterate over object values: `Object.values` returns an array of them. +- 배열의 합을 얻기 위해 사용된 `arr.reduce` 는 장을 참고하세요. +- 반복적인 객체 값을 얻기 위해 `for(val of Object.values (obj))` 를 사용하였습니다: `Object.values`는 그것의 배열을 반환합니다. -## Recursive structures +## 재귀적인 구조들 -A recursive (recursively-defined) data structure is a structure that replicates itself in parts. +재귀 (재귀적으로 정의된) 데이터 구조라는 것은 자체적으로 복제하는 구조입니다. -We've just seen it in the example of a company structure above. +위의 회사 구조의 예를 통해서 살펴보았습니다. -A company *department* is: -- Either an array of people. -- Or an object with *departments*. +회사 *department* 는 다음과 같이 구성되어 있었습니다. +- 사람들의 배열. +- 또는 *department* 가 있는 오브젝트. -For web-developers there are much better-known examples: HTML and XML documents. +웹 개발자에게는 HTML 및 XML 문서와 같이 훨씬 익숙한 예제가 있죠. -In the HTML document, an *HTML-tag* may contain a list of: -- Text pieces. -- HTML-comments. -- Other *HTML-tags* (that in turn may contain text pieces/comments or other tags etc). +HTML 문서에서 *HTML-태그*는 다음 목록을 포함할 수 있습니다. +- 텍스트 조각. +- HTML-주석. +- 다른 *HTML-태그* (텍스트 / 주석 또는 기타 태그 등을 포함). -That's once again a recursive definition. +이러한 것이 재귀적인 정의입니다. -For better understanding, we'll cover one more recursive structure named "Linked list" that might be a better alternative for arrays in some cases. +이해를 돕기위해, 배열에 대해 더 좋은 방법으로 접근할 수 있는 "연결 리스트"라는 재귀적인 구조를 살펴보죠. -### Linked list +### 연결 리스트 (Linked list) -Imagine, we want to store an ordered list of objects. +객체에 정렬된 목록을 저장한다고 상상해 보세요. -The natural choice would be an array: +일반적인 선택은 배열(Array)일 것입니다 : ```js let arr = [obj1, obj2, obj3]; ``` -...But there's a problem with arrays. The "delete element" and "insert element" operations are expensive. For instance, `arr.unshift(obj)` operation has to renumber all elements to make room for a new `obj`, and if the array is big, it takes time. Same with `arr.shift()`. +...하지만 배열에는 문제가 있습니다. "요소 삭제" 및 "요소 삽입" 작업이 어렵습니다. 특히 `arr.unshift(obj)` 연산은 새로운 `obj` 를 위한 공간을 만들기 위해 모든 원소의 번호를 다시 지정해야 하고 큰 배열에는 시간이 걸립니다. `arr.shift()` 도 동일합니다. -The only structural modifications that do not require mass-renumbering are those that operate with the end of array: `arr.push/pop`. So an array can be quite slow for big queues. + 큰 비용을 치루지 않고 모두 변경할 수 있는 유일한 방법은`arr.push/pop` 을 사용해 배열의 끝을 이용해 작업하는 것입니다. 여전히 배열은 크면 클수록 상당히 느릴 수 있습니다. -Alternatively, if we really need fast insertion/deletion, we can choose another data structure called a [linked list](https://en.wikipedia.org/wiki/Linked_list). + 빠른 삽입 / 삭제가 정말로 필요한 경우에는 [연결 리스트(Linked List)](https://en.wikipedia.org/wiki/Linked_list) 라는 다른 데이터 구조를 선택할 수 있습니다. -The *linked list element* is recursively defined as an object with: +*연결 리스트의 요소* 는 다음과 같이 재귀적인 객체로 정의됩니다. - `value`. -- `next` property referencing the next *linked list element* or `null` if that's the end. +- `next` 다음 *연결 리스트의 요소*를 참조하는 프로퍼티 또는 끝인 경우 `null`. -For instance: +예를 들면 ```js let list = { @@ -442,11 +446,11 @@ let list = { }; ``` -Graphical representation of the list: +리스트를 시각적으로 표현하 ![linked list](linked-list.png) -An alternative code for creation: +코드로는 다음과 같습니다. ```js no-beautify let list = { value: 1 }; @@ -455,9 +459,9 @@ list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; ``` -Here we can even more clearer see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element. +여러 객체가 있는것이 분명해 집니다. 각 객체는 이웃을 가리키는 `value`와 `next`를 가지고 있죠. `list` 변수는 체인의 첫 번째 객체이므로, `next` 포인터를 따라가면 모든 요소에 도달할 수 있습니다. -The list can be easily split into multiple parts and later joined back: +리스트를 여러 부분으로 쉽게 나눌 수 있으며 다시 합칠 수도 있습니다. ```js let secondList = list.next.next; @@ -472,9 +476,9 @@ To join: list.next.next = secondList; ``` -And surely we can insert or remove items in any place. +확실하게 어디에서나 아이템을 추가하거나 제거할 수 있습니다. -For instance, to prepend a new value, we need to update the head of the list: +예를 들어 새 값을 앞에 붙이려면 리스트 헤드를 갱신해야 합니다. ```js let list = { value: 1 }; @@ -490,7 +494,7 @@ list = { value: "new item", next: list }; ![linked list](linked-list-0.png) -To remove a value from the middle, change `next` of the previous one: +중간에서 값을 제거하려면 이전 값의 `next`를 변경해야 합니다. ```js list.next = list.next.next; @@ -498,35 +502,35 @@ list.next = list.next.next; ![linked list](linked-list-remove-1.png) -We made `list.next` jump over `1` to value `2`. The value `1` is now excluded from the chain. If it's not stored anywhere else, it will be automatically removed from the memory. +`list.next`가 `1`을 뛰어넘어서`2` 값을 얻었습니다. 이제 값 `1`이 체인에서 제외됩니다. 다른 곳에 저장되지 않으면 자동으로 메모리에서 제거됩니다. -Unlike arrays, there's no mass-renumbering, we can easily rearrange elements. +배열과는 달리, 대량으로 번호 할당하지 않았으므로 요소를 쉽게 재배열할 수 있습니다. -Naturally, lists are not always better than arrays. Otherwise everyone would use only lists. +그러나 항상 리스트가 배열보다 낫지는 않습니다. 그렇다면 모두 리스트만 사용하겠죠. -The main drawback is that we can't easily access an element by its number. In an array that's easy: `arr[n]` is a direct reference. But in the list we need to start from the first item and go `next` `N` times to get the Nth element. +리스트의 가장 큰 단점은 인덱스(번호)로 요소에 쉽게 액세스할 수 없다는 점입니다. 배열에서는 `arr[n]` 처럼 해당요소에 바로 접근할 수 있습니다. 그러나 리스트에서 첫 번째 항목부터 시작하여 N 번째 값을 얻기 위해서는 `next` 를 `N` 번 이동해야 합니다. -...But we don't always need such operations. For instance, when we need a queue or even a [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- the ordered structure that must allow very fast adding/removing elements from both ends. +... 이렇게 하지않아도 대기열(queue) 또는 [양단 대기열(deque)](https://en.wikipedia.org/wiki/Double-ended_queue) 를 사용해 양 끝의 요소를 매우 빠르게 추가 / 제거할 수 있습니다만 -Sometimes it's worth to add another variable named `tail` to track the last element of the list (and update it when adding/removing elements from the end). For large sets of elements the speed difference versus arrays is huge. +가끔 리스트의 마지막에 `tail`이라는 다른 이름을 사용해서 마지막 요소를 추가하는게 효과적일 수 있습니다. (그리고 끝에서 요소를 추가하거나 제거할때 업데이트 합니다). 여전히 큰 요소들로 구성되었을때 배열과 리스트의 속도차이는 큽니다. -## Summary +## 요약 -Terms: -- *Recursion* is a programming term that means a "self-calling" function. Such functions can be used to solve certain tasks in elegant ways. +용어: +- *재귀* 는 "자체 호출" 을 의미하는 프로그래밍 용어다. 재귀를 사용하여 특정 작업을 더 멋진 방식으로 해결할 수 있다. - When a function calls itself, that's called a *recursion step*. The *basis* of recursion is function arguments that make the task so simple that the function does not make further calls. + 함수가 자신을 호출할 때 *재귀 단계* 라고 한다. 재귀의 *base* 은 함수를 더 간단하게 만들어서 함수가 더 호출하지 못 하는 단계의 함수 인수이다. -- A [recursively-defined](https://en.wikipedia.org/wiki/Recursive_data_type) data structure is a data structure that can be defined using itself. +- [재귀적으로 정의된](https://en.wikipedia.org/wiki/Recursive_data_type) 데이터 구조는 자체적으로 정의할 수 있는 데이터 구조이다. - For instance, the linked list can be defined as a data structure consisting of an object referencing a list (or null). + 예를 들어 연결 리스트는 목록을 참조하는 객체 (또는 null)로 구성된 데이터 구조로 정의될 수 있다. ```js - list = { value, next -> list } + list = {value, next -> list} ``` - Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they branch and every branch can have other branches. + 여기서 다룬 HTML 요소 또는 회사부서 와 같은 구조도 일반적인 재귀적인 구조이다. 가지고 있는 모든 분기마다 다른 분기를 가질 수 있기 때문이다. - Recursive functions can be used to walk them as we've seen in the `sumSalary` example. + 이 장에서는 재귀적인 함수 `sumSalary` 를 사용하여 그 분기를 순차적으로 진행하는 방법을 살펴보았습니다. -Any recursive function can be rewritten into an iterative one. And that's sometimes required to optimize stuff. But for many tasks a recursive solution is fast enough and easier to write and support. +모든 재귀 함수는 반복적인 함수로 다시 작성할 수 있습니다. 재귀적인 함수는 최적화를 요구하지만 많은 작업에서 재귀적인 접근법은 더 빠르고 쉽게 작성할 수 있고 유지보수가 수월한 코드를 제공합니다. \ No newline at end of file diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md index a98d8eddda..abec10e0a5 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md @@ -1,20 +1,20 @@ -# Rest parameters and spread operator +# 나머지 매개변수와 전개 연산자 -Many JavaScript built-in functions support an arbitrary number of arguments. +많은 자바스크립트 내장 함수는 임의의 수의 인수를 지원합니다. -For instance: +예를 들어 -- `Math.max(arg1, arg2, ..., argN)` -- returns the greatest of the arguments. -- `Object.assign(dest, src1, ..., srcN)` -- copies properties from `src1..N` into `dest`. -- ...and so on. +- `Math.max(arg1, arg2, ..., argN)` -- 가장 큰 인수를 반환합니다. +- `Object.assign(dest, src1, ..., srcN)` -- `src1..N` 에서 `dest` 로 속성을 복사. +- ...등등. -In this chapter we'll learn how to do the same. And, more importantly, how to feel comfortable working with such functions and arrays. +이번 챕터에서는 이러한 방법을 살펴보겠습니다. 그리고 중요한 것은 이러한 함수 및 배열을 사용해서 편하게 작업하는 방법을 배워보겠습니다. -## Rest parameters `...` +## 나머지 매개변수 `...` -A function can be called with any number of arguments, no matter how it is defined. +어떤 함수가 정의되더라도 함수의 인수는 여러개로 호출할 수 있습니다. -Like here: +예를 들면 ```js run function sum(a, b) { return a + b; @@ -23,14 +23,14 @@ function sum(a, b) { alert( sum(1, 2, 3, 4, 5) ); ``` -There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted. +"초과된" 인수 때문에 오류가 발생하지는 않습니다. 그러나 결과에서 처음 두 개만 계산되죠. -The rest parameters can be mentioned in a function definition with three dots `...`. They literally mean "gather the remaining parameters into an array". +나머지 매개변수는 세 개의 점 '...'이 있는 함수 선언에서 언급할 수 있습니다. 표현 그대로 "나머지 매개변수를 배열로 모으는" 것을 의미합니다. -For instance, to gather all arguments into array `args`: +예를 들어 모든 인수를 배열 `args`에 모으려면 ```js run -function sumAll(...args) { // args is the name for the array +function sumAll(...args) { // args 가 배열의 이름입니다 let sum = 0; for (let arg of args) sum += arg; @@ -43,9 +43,9 @@ alert( sumAll(1, 2) ); // 3 alert( sumAll(1, 2, 3) ); // 6 ``` -We can choose to get the first parameters as variables, and gather only the rest. +첫 번째 매개변수를 변수로 가져오고 나머지 매개변수 만 수집 할 수 있습니다. -Here the first two arguments go into variables and the rest go into `titles` array: +여기서 처음 두 인수는 변수에 들어가고 나머지는 `titles` 배열에 들어갑니다. ```js run function showName(firstName, lastName, ...titles) { @@ -61,23 +61,23 @@ function showName(firstName, lastName, ...titles) { showName("Julius", "Caesar", "Consul", "Imperator"); ``` -````warn header="The rest parameters must be at the end" -The rest parameters gather all remaining arguments, so the following does not make sense and causes an error: +````warn header="나머지 매개변수는 항상 마지막에 있어야 합니다" +나머지 매개변수는 나머지 모든 인수를 수집하므로 다음은 오류입니다. ```js -function f(arg1, ...rest, arg2) { // arg2 after ...rest ?! +function f(arg1, ...rest, arg2) { // arg2 후에 ...rest ?! // error } ``` -The `...rest` must always be last. +`...rest`는 항상 마지막에 있어야 합니다. ```` -## The "arguments" variable +## "arguments" 변수 -There is also a special array-like object named `arguments` that contains all arguments by their index. +`arguemnts`라는 이름의 특별한 유사-배열-객체(array-like object)가 인덱스에 의해 모든 인수를 포함하고 있습니다. -For instance: +예를 들면 : ```js run function showName() { @@ -85,7 +85,7 @@ function showName() { alert( arguments[0] ); alert( arguments[1] ); - // it's iterable + // 반복 가능하다 // for(let arg of arguments) alert(arg); } @@ -96,20 +96,20 @@ showName("Julius", "Caesar"); showName("Ilya"); ``` -In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function, no matter their total number. +과거의 자바스크립트에는 나머지 매개변수가 존재하지 않았고 `arguments`를 사용하는 것이 매개변수의 숫자에 관계없이 모든 인수를 사용하는 유일한 방법이었습니다. -And it still works, we can use it today. +그리고 `arguments`는 여전히 작동하고 사용할 수 있습니다. -But the downside is that although `arguments` is both array-like and iterable, it's not an array. It does not support array methods, so we can't call `arguments.map(...)` for example. +그러나 `arguments` 의 단점은 배열과 같이 반복은 할 수 있지만 배열은 아닙니다. 배열 메서드를 지원하지 않아서, `arguments.map (...)`을 호출할 수 없습니다. -Also, it always contains all arguments. We can't capture them partially, like we did with rest parameters. +또한 언제나 모든 인수를 포함합니다. 나머지 매개변수와 마찬가지로 부분적으로 사용할 수 없습니다. -So when we need these features, then rest parameters are preferred. +이런 이유로 현재는 나머지 매개변수가 선호됩니다. -````smart header="Arrow functions do not have `\"arguments\"`" -If we access the `arguments` object from an arrow function, it takes them from the outer "normal" function. +````smart header="`\"arguments\" 는 화살표 함수에는 없습니다`" +화살표 함수에서 `arguments` 객체에 접근하면, 그것들은 외부에 있는 "보통" 함수로부터 가져옵니다. -Here's an example: +다음은 그 예입니다. ```js run function f() { @@ -121,23 +121,23 @@ f(1); // 1 ``` ```` -As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either. +그러나, 화살표 함수에는 그 함수만을 위한 `this` 가 없습니다. 그래서 `arguments` 객체도 없습니다. -## Spread operator [#spread-operator] +## 전개 연산자 [# spread-operator] -We've just seen how to get an array from the list of parameters. +매개변수를 배열로 가져오는 방법을 살펴보았습니다. -But sometimes we need to do exactly the reverse. +그런데 가끔 그것의 역행인 작업이 필요할때가 있습니다. -For instance, there's a built-in function [Math.max](mdn:js/Math/max) that returns the greatest number from a list: +예를 들어 [Math.max](mdn:js/Math/max) 라는 내장함수는 목록에서 가장 큰 숫자를 반환합니다. ```js run alert( Math.max(3, 5, 1) ); // 5 ``` -Now let's say we have an array `[3, 5, 1]`. How do we call `Math.max` with it? +배열 `[3, 5, 1]` 이 있다고 할때 `Math.max`를` 어떻게 호출할 수 있을까요? -Passing it "as is" won't work, because `Math.max` expects a list of numeric arguments, not a single array: +`Math.max`는 단일 배열이 아닌 목록으로된 숫자 인자를 인수로 받기 때문에 "배열" 그대로 넘기면 작동하지 않습니다 ```js run let arr = [3, 5, 1]; @@ -147,21 +147,22 @@ alert( Math.max(arr) ); // NaN */!* ``` -And surely we can't manually list items in the code `Math.max(arr[0], arr[1], arr[2])`, because we may be unsure how many there are. As our script executes, there could be a lot, or there could be none. And that would get ugly. +확실히 `Math.max (arr [0], arr [1], arr [2])` 코드에서는 배열항목을 수동으로 나열할 수 없습니다. +왜냐하면 스크립트가 실행될 때 배열이 더 클 수도 있고 작을 수도 있고 혹은 비어있을지 알 수 없기 때문이죠. 이것이 잘못된 결과를 가져올 수 있습니다. -*Spread operator* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite. +*전개 연산자* 가 해결해 줍니다! 전개 연산자는 나머지 매개변수와 비슷하게 보이고 `...` 을 사용하지만, 사실은 반대로 작동합니다. -When `...arr` is used in the function call, it "expands" an iterable object `arr` into the list of arguments. +`... arr`이 함수에서 호출 될때, iterable(반복 가능한) 객체 `arr`을 인수들의 목록으로 "확장" 합니다. For `Math.max`: ```js run let arr = [3, 5, 1]; -alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments) +alert( Math.max(...arr) ); // 5 (배열을 인자들의 목록으로 바꾼다) ``` -We also can pass multiple iterables this way: +다음과 같이 여러 iterable을 전달할 수도 있습니다. ```js run let arr1 = [1, -2, 3, 4]; @@ -170,7 +171,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(...arr1, ...arr2) ); // 8 ``` -We can even combine the spread operator with normal values: +전개 연산자를 일반 값과 혼합해 사용할 수도 있습니다. ```js run @@ -180,7 +181,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25 ``` -Also, the spread operator can be used to merge arrays: +또한 전개 연산자를 사용하여 배열을 병합할 수 있습니다. ```js run let arr = [3, 5, 1]; @@ -190,12 +191,12 @@ let arr2 = [8, 9, 15]; let merged = [0, ...arr, 2, ...arr2]; */!* -alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2) +alert(merged); // 0,3,5,1,2,8,9,15 (0, 다음은 arr, 다음은 2, 다음은 arr2) ``` -In the examples above we used an array to demonstrate the spread operator, but any iterable will do. +위의 예제에서는 전개 연산자를 보여주기 위해 배열을 사용했지만, 다른 어떠한 iterable 작업이라면 가능합니다. -For instance, here we use the spread operator to turn the string into array of characters: +다음 예제는 전개 연산자를 사용하여 문자열을 문자 배열로 변환합니다. ```js run let str = "Hello"; @@ -203,11 +204,13 @@ let str = "Hello"; alert( [...str] ); // H,e,l,l,o ``` -The spread operator internally uses iterators to gather elements, the same way as `for..of` does. +전개 연산자는 `for..of` 와 같은 방식으로 내부적으로 iterators(반복자들)을 사용하여 요소를 수집합니다. -So, for a string, `for..of` returns characters and `...str` becomes `"H","e","l","l","o"`. The list of characters is passed to array initializer `[...str]`. +그래서, 문자일경우, `for..of` 는 문자를 반환하고 `...str`은 `"H","e","l","l","o"`가 됩니다. 문자의 리스트는 `[...str]` 배열 이니셜라이저로 넘겨집니다. -For this particular task we could also use `Array.from`, because it converts an iterable (like a string) into an array: +이 특별한 작업을 위해서 iterable `Array.from`을 배열로 변환하기 때문에 `Array.from`을 사용할 수도 있습니다 : + +이러한 iterable (문자열 같은) 객체를 배열로 변환하는 특수한 작업에는 `Array.from`을 사용할 수도 있습니다. ```js run let str = "Hello"; @@ -216,30 +219,30 @@ let str = "Hello"; alert( Array.from(str) ); // H,e,l,l,o ``` -The result is the same as `[...str]`. +결과는`[...str]`과 같습니다. -But there's a subtle difference between `Array.from(obj)` and `[...obj]`: +그러나 `Array.from (obj)`와 `[... obj]`에는 미묘한 차이가 있습니다 : -- `Array.from` operates on both array-likes and iterables. -- The spread operator operates only on iterables. +- `Array.from` 은 유사-배열과 iterables(반복 가능한) 둘 다에서 작동합니다. +- 전개 연산자는 iterable 객체 에서만 작동합니다. -So, for the task of turning something into an array, `Array.from` tends to be more universal. +그래서, 배열로 뭔가를 돌리는 작업을 할때는 `Array.from` 을 사용하는 경향이 있습니다. -## Summary +## 요약 -When we see `"..."` in the code, it is either rest parameters or the spread operator. +`"..."`는 코드에서 볼 때, 나머지 매개변수 또는 전개 연산자이다. -There's an easy way to distinguish between them: +나머지 매개변수와 전개 연산자를 서로 구분할 수 있는 쉬운 방법이 있다. -- When `...` is at the end of function parameters, it's "rest parameters" and gathers the rest of the list of arguments into an array. -- When `...` occurs in a function call or alike, it's called a "spread operator" and expands an array into a list. +- `...`이 함수 매개변수의 끝에 있을 때, 그것은 "나머지 매개변수"이고 나머지 인수 목록을 배열로 모으는 것이다. +- `...`이 함수 호출과 비슷하게 발생하면, 그것은 "전개 연산자"이고 배열을 리스트로 확장하는 것이다. -Use patterns: +패턴 사용하기 -- Rest parameters are used to create functions that accept any number of arguments. -- The spread operator is used to pass an array to functions that normally require a list of many arguments. +- 나머지 매개변수는 주로 여러 개의 인수를 허용하는 함수에 사용된다. +- 전개 연산자는 일반적으로 많은 인수 목록을 요구하는 함수에 배열을 전달하는 데 사용된다. -Together they help to travel between a list and an array of parameters with ease. +두 방법 모두 목록과 매개변수 배열 간의 이동을 쉽게 돕습니다. -All arguments of a function call are also available in "old-style" `arguments`: array-like iterable object. +여전히 모든 함수 호출의 인수는 "오래된-방식" 인 `arguments`(배열 같은 iterable 객체)을 사용할 수 있습니다. \ No newline at end of file diff --git a/1-js/06-advanced-functions/03-closure/1-counter-independent/task.md b/1-js/06-advanced-functions/03-closure/1-counter-independent/task.md index e8c17dd31c..39a00d4ce5 100644 --- a/1-js/06-advanced-functions/03-closure/1-counter-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/1-counter-independent/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Are counters independent? +# 카운터는 독립적입니까? -Here we make two counters: `counter` and `counter2` using the same `makeCounter` function. +여기서 우리는 두 개의 카운터를 만듭니다 : `counter` 와 `counter2` 는 같은 `makeCounter` 함수를 사용합니다. -Are they independent? What is the second counter going to show? `0,1` or `2,3` or something else? +그것들은 독립적입니까? 두 번째 카운터 결과는 무엇일까요? `0,1` 또는`2,3` 또는 다른 값인가요? ```js function makeCounter() { diff --git a/1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md b/1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md index d770b0ffc9..60c5e699a6 100644 --- a/1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md +++ b/1-js/06-advanced-functions/03-closure/2-counter-object-independent/task.md @@ -1,12 +1,11 @@ importance: 5 --- +# 카운터 객체 -# Counter object +여기서 counter 객체는 생성자 함수의 도움으로 만들어집니다. -Here a counter object is made with the help of the constructor function. - -Will it work? What will it show? +이것이 작동할까요? 결과는 어떨까요? ```js function Counter() { diff --git a/1-js/06-advanced-functions/03-closure/3-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/3-function-in-if/task.md index d0dbbeb111..d932389589 100644 --- a/1-js/06-advanced-functions/03-closure/3-function-in-if/task.md +++ b/1-js/06-advanced-functions/03-closure/3-function-in-if/task.md @@ -1,7 +1,6 @@ -# Function in if - -Look at the code. What will be result of the call at the last line? +# if 함수 +코드를보세요. 마지막 줄에서 전화 한 결과는 무엇입니까? ```js run let phrase = "Hello"; diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md b/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md index a6679cd209..9cb7891b9b 100644 --- a/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md +++ b/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md @@ -6,7 +6,7 @@ Like this: function sum(a) { return function(b) { - return a + b; // takes "a" from the outer lexical environment + return a + b; // takes "a" from the outer 렉시컬 환경 }; } diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md index b45758562e..6b7a58cc66 100644 --- a/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md +++ b/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md @@ -1,14 +1,13 @@ importance: 4 --- +# 클로져와 합계 -# Sum with closures +`sum (a) (b) = a + b`와 같이 작동하는 `sum` 함수를 작성하십시오. -Write function `sum` that works like this: `sum(a)(b) = a+b`. +맞습니다, 정확하게 이 방법은 이중 괄호 (실수 유형이 아님)를 사용해야 합니다. -Yes, exactly this way, using double parentheses (not a mistype). - -For instance: +예를 들면 : ```js sum(1)(2) = 3 diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md b/1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md index d1c39f949c..af6e8e12b6 100644 --- a/1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md +++ b/1-js/06-advanced-functions/03-closure/6-filter-through-function/task.md @@ -1,25 +1,23 @@ importance: 5 --- +# 필터 통과 기능 +우리는 어레이를 위한 `arr.filter (f)` 라는 내장 메소드를 가지고 있습니다. 이 함수는 `f` 함수를 통해 모든 요소를 필터링합니다. `true` 를 돌려주는 경우, 결과의 배열에 그 요소가 반환됩니다. -# Filter through function +"사용할 준비가 된" 필터 세트 만들기 : -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. +- `inBetween(a, b)` -- a와 b 또는 그와 동등한 것 (포함) +- `inArray([...])` -- 주어진 배열에서 -Make a set of "ready to use" filters: +사용법은 다음과 같아야 합니다: -- `inBetween(a, b)` -- between `a` and `b` or equal to them (inclusively). -- `inArray([...])` -- in the given array. +- `arr.filter(inBetween(3,6))` -- 3과 6 사이의 값만 선택합니다. +- `arr.filter(inArray([1,2,3]))` -- `[1,2,3]`의 멤버 중 하나와 일치하는 요소만 선택합니다. -The usage must be like this: - -- `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]`. - -For instance: +예를 들면 : ```js -/* .. your code for inBetween and 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/7-sort-by-field/task.md b/1-js/06-advanced-functions/03-closure/7-sort-by-field/task.md index 08fb5cc343..2f87937e43 100644 --- a/1-js/06-advanced-functions/03-closure/7-sort-by-field/task.md +++ b/1-js/06-advanced-functions/03-closure/7-sort-by-field/task.md @@ -1,10 +1,8 @@ importance: 5 --- - -# Sort by field - -We've got an array of objects to sort: +# 필드로 정렬 +정렬 할 객체 배열이 있습니다. ```js let users = [ @@ -14,7 +12,7 @@ let users = [ ]; ``` -The usual way to do that would be: +그렇게하는 일반적인 방법은 다음과 같습니다. ```js // by name (Ann, John, Pete) @@ -24,13 +22,13 @@ users.sort((a, b) => a.name > b.name ? 1 : -1); users.sort((a, b) => a.age > b.age ? 1 : -1); ``` -Can we make it even less verbose, like this? +우리가 덜 장황하게 만들 수 있을까요? ```js users.sort(byField('name')); users.sort(byField('age')); ``` -So, instead of writing a function, just put `byField(fieldName)`. +따라서, 함수를 작성하는 대신 `byField (fieldName)`을 입력하십시오. -Write the function `byField` that can be used for that. +그것을 사용할 수 있는 byField 함수를 작성하십시오. diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/task.md b/1-js/06-advanced-functions/03-closure/8-make-army/task.md index ede8fd0458..646c7fc5c3 100644 --- a/1-js/06-advanced-functions/03-closure/8-make-army/task.md +++ b/1-js/06-advanced-functions/03-closure/8-make-army/task.md @@ -1,12 +1,10 @@ importance: 5 --- +# 기능의 군대들 +다음 코드는 `shooters` 배열을 만듭니다. -# Army of functions - -The following code creates an array of `shooters`. - -Every function is meant to output its number. But something is wrong... +모든 함수는 숫자를 출력합니다. 그러나 뭔가 잘못되었습니다 ... ```js run function makeArmy() { @@ -31,5 +29,4 @@ army[5](); // and number 5 also outputs 10... // ... all shooters show 10 instead of their 0, 1, 2, 3... ``` -Why all shooters show the same? Fix the code so that they work as intended. - +왜 모든 shooters 는 똑같아 보일까요? 코드를 고쳐서 의도한대로 동작하게 해보세요. diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md index ac0e44c63c..ec327e9129 100644 --- a/1-js/06-advanced-functions/03-closure/article.md +++ b/1-js/06-advanced-functions/03-closure/article.md @@ -1,21 +1,21 @@ -# Closure +# 클로져 -JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at one moment, then copied to another variable or passed as an argument to another function and called from a totally different place later. +자바스크립트는 매우 기능 지향적인 언어입니다. 많은 자유도를 가지고 있습니다. 한순간에 함수를 생성한 다음 다른 변수에 복사하거나 다른 함수에 인수로 전달할 수 있으며 나중에 완전히 다른 곳에서 호출할 수 있습니다. -We know that a function can access variables outside of it; this feature is used quite often. +함수가 외부의 변수에 접근할 수 있다는 것을 알고 있습니다. 이 기능은 꽤 자주 사용됩니다. -But what happens when an outer variable changes? Does a function get the most recent value or the one that existed when the function was created? +그러나 외부 변수가 변경되면 어떻게 됩니까? 함수가 가장 최근의 값이나 함수가 생성되었을 때 존재했던 값을 가져옵니까? -Also, what happens when a function travels to another place in the code and is called from there -- does it get access to the outer variables of the new place? +또한 함수가 코드의 다른 위치로 이동하여 그곳에서 호출되면 어떤 일이 발생할까요 - 새로운 곳의 외부 변수에 접근할 수 있습니까? -Different languages behave differently here, and in this chapter we cover the behaviour of JavaScript. +다른 언어는 여기에서 다르게 동작하며, 이 장에서는 자바스크립트의 동작을 다룹니다. -## A couple of questions +## 몇 가지 질문 -Let's consider two situations to begin with, and then study the internal mechanics piece-by-piece, so that you'll be able to answer the following questions and more complex ones in the future. +두 가지 상황을 먼저 고려한 다음, 내부 역학을 한 조각씩 공부하여, 향후에 다음 질문과 더 복잡한 질문에 답할 수 있게 하십시오. -1. The function `sayHi` uses an external variable `name`. When the function runs, which value is it going to use? +1. 함수 `sayHi`는 외부 변수 `name`을 사용합니다. 함수가 실행되면 어떤 값을 사용할 것입니까? ```js let name = "John"; @@ -27,16 +27,16 @@ Let's consider two situations to begin with, and then study the internal mechani name = "Pete"; *!* - sayHi(); // what will it show: "John" or "Pete"? + sayHi(); // 무엇을 보여줄까요: "John" 아니면 "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. + 이러한 상황은 브라우저 및 서버 측 개발 모두에게 공통적입니다. 함수는 예를 들어 사용자의 동작 또는 네트워크 요청 후 작성된 것보다 나중에 실행되도록 스케줄 될 수 있습니다. + + 그럼 질문은 : 그것이 가장 최근의 변경된 내용을 가져올까요? - So, the question is: does it pick up the latest changes? - -2. The function `makeWorker` makes another function and returns it. That new function can be called from somewhere else. Will it have access to the outer variables from its creation place, or the invocation place, or both? +2. 함수`makeWorker`는 다른 함수를 만들어서 그것을 반환합니다. 그 새로운 기능은 다른 곳에서 호출할 수 있습니다. 외부 변수에 대한 액세스 권한을 생성 위치 또는 호출 위치에서 또는 둘 다 사용할 수 있습니까? ```js function makeWorker() { @@ -54,74 +54,74 @@ Let's consider two situations to begin with, and then study the internal mechani // call it *!* - work(); // what will it show? "Pete" (name where created) or "John" (name where called)? + work(); // 무엇을 보여줄까요? "Pete" (생성된이름) or "John" (불려진이름)? */!* ``` -## Lexical Environment +## 렉시컬(lexical, 정적, 어휘적) 환경 -To understand what's going on, let's first discuss what a "variable" actually is. +무슨 일이 벌어지고 있는지 이해하려면 먼저 "변수"가 실제로 무엇인지 논의해 봅시다. -In JavaScript, every running function, code block, and the script as a whole have an associated object known as the *Lexical Environment*. +자바스크립트에서 실행 중인 모든 함수, 코드 블록 및 스크립트에는 *렉시컬 환경* 라는 알려진 객체가 있습니다. -The Lexical Environment object consists of two parts: +렉시컬 환경 객체는 두 부분으로 구성됩니다. -1. *Environment Record* -- an object that has all local variables as its properties (and some other information like the value of `this`). -2. A reference to the *outer lexical environment*, usually the one associated with the code lexically right outside of it (outside of the current curly brackets). +1. *환경 레코드* - 모든 로컬 변수를 속성으로 가진 객체 (그리고 `this` 값과 같은 다른 정보). +*외부 렉시컬 환경* 에 대한 참조. 일반적으로 바깥쪽의 어휘적으로 바뀐 코드와 연관되어 있습니다. (현재 중괄호 바깥쪽). -**So, 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".** +**따라서 "변수"는 특별한 내부 객체인 환경 레코드의 속성일 뿐입니다. "변수를 가져오거나 변경하려면" "해당 객체의 속성을 가져오거나 변경하려면"을 의미합니다.** -For instance, in this simple code, there is only one Lexical Environment: +예를 들어, 이 간단한 코드에는 하나의 렉시컬 환경만 있습니다. -![lexical environment](lexical-environment-global.png) +![렉시컬 환경](lexical-environment-global.png) -This is a so-called global Lexical Environment, associated with the whole script. For browsers, all `