01. 함수 : 선언적 함수

함수는 실행문이며 반복적으로 사용 가능합니다.
또한, 필요한 곳에서 호출하여 사용할 수 있으며, 명령문들을 묶어서 재사용 가능한 단위로 만들어줍니다.

{
    function func(){
        console.log("1. 함수가 실행되었습니다.");
    }
    func();
}

function func(){...}: function을 사용하여 함수를 선언하고, 함수의 이름을 func로 지정했습니다.
console.log("1. 함수가 실행되었습니다.");: 함수의 내에서 실행됩니다.
문자열 "실행되었습니다."를 콘솔에 출력하는 역할을 합니다.
func();: 함수를 호출하는 부분입니다.
함수를 호출하면 콘솔에 "1. 함수가 실행되었습니다."라는 메시지가 출력됩니다.

결과 확인하기
1. 함수가 실행되었습니다.

02. 함수 : 익명 함수

익명함수는 이름 없이 정의되는 함수입니다.
따라서 함수를 호출하려면 변수에 할당한 후 해당 변수 이름을 사용하여 호출합니다.
함수를 변수로 다루거나, 함수를 인자로(콜백함수) 전달하거나, 함수를 반환하는 고차 함수를 구현할 수 있습니다.

{
    const func = function(){
        console.log("2. 함수가 실행되었습니다.");
    }
    func();
}

const func = function(){}: 함수를 정의하고 변수 func에 할당합니다.
console.log("2. 함수가 실행되었습니다.");: 콘솔(console)에 "1. 함수가 실행되었습니다."라는 메시지를 출력하는 역할을 합니다.
func();: 함수를 호출하는 부분입니다. func 변수를 호출하면, 변수에 할당된 함수가 실행됩니다.

결과 확인하기
2. 함수가 실행되었습니다.

03. 함수 : 매개변수 함수

매개변수를 가지는 함수를 정의하고, 해당 함수를 호출하는 예제입니다.
매개변수를 사용하면 함수 내부로 데이터를 전달할 수 있습니다.

{
    function func(str){
        console.log(str);
    }
    func("3. 함수가 실행되었습니다.");
}

function func(str): 하나의 매개변수 str을 받는 func라는 이름의 함수를 정의합니다.
console.log(str);: 매개변수 str을 콘솔에 출력합니다.
func("3. 함수가 실행되었습니다."); 부분은 func 함수를 호출하여 매개변수로 "3. 함수가 실행되었습니다." 문자열을 전달합니다.

결과 확인하기
3. 함수가 실행되었습니다.

04. 함수 : 리턴값 함수

리턴값(return value)은 함수가 실행된 후 결과로 반환하는 값을 나타냅니다.
함수의 리턴값은 함수 호출 시에 변수에 저장하거나 다른 계산에 사용할 수 있습니다.
함수를 사용하여 특정 작업을 수행하고 그 결과를 다른 부분에서 활용할 때 리턴값이 유용하게 활용됩니다.
아래는 함수를 호출하여 반환된 값을 콘솔에 출력하는 예제입니다.

{
    function func(){
        return "4. 함수가 실행되었습니다.";
    }
    console.log(func());
}

return "실행되었습니다.";: 함수가 호출된 결과로 문자열 "4. 함수가 실행되었습니다."를 반환하도록 설정되어 있습니다.
console.log(func());: 반환된 값을 console.log() 함수를 사용하여 콘솔에 출력합니다.

결과 확인하기
4. 함수가 실행되었습니다.

05. 함수 : 매개변수 + 리턴값 함수

매개변수로 함수로 데이터를 전달하고, 리턴값으로 함수가 작업을 완료한 후 결과를 반환하는 예제입니다.

{
    function func(str){
        return str;
    }
    console.log(func("5. 함수가 실행되었습니다."));
}

function func(str) {}: 함수 내부에서 사용할 수 있는 하나의 매개변수 str을 받습니다.
console.log(func("5. 함수가 실행되었습니다."));: 함수를 호출하여 매개변수 str에 문자열 "5. 함수가 실행되었습니다."를 전달합니다.
함수 내부의 코드는 매개변수 str에 전달된 값인 "5. 함수가 실행되었습니다."를 그대로 반환(return)합니다.
함수는 입력값(매개변수)을 받아서 특정 작업을 수행하고, 결과값(리턴값)을 반환할 수 있습니다.

결과 확인하기
5. 함수가 실행되었습니다.

06. 화살표 함수(=>) + 생략 : 선언적 함수

화살표 함수는 함수를 더 간결하게 정의할 수 있고, 주로 익명 함수(Anonymous Function)로 사용됩니다.

{
    func = () => {
        console.log("6. 함수가 실행되었습니다.");
    }
    func();
}

선언적 함수를 화살표 함수로 변환할 때 주의해야 할 사항:
1. 함수 이름의 제거: 화살표 함수는 익명 함수로, 이름을 가질 수 없습니다.
함수 이름을 제거하고 변수에 할당합니다. 2. 함수 표현식: 화살표 함수는 함수 표현식(Function Expression)으로 사용됩니다.
이것은 함수를 변수에 할당할 수 있게 해주므로 나중에 호출할 수 있습니다.
() => { ... } 형식으로 표현됩니다.
() =>는 매개변수 부분이며, { ... } 안에 함수의 본문을 작성합니다. 3. 리턴 값 생략: 화살표 함수의 경우, 단일 표현식의 결과를 자동으로 반환하여 'return'을 생략 가능합니다.
그러나, 중괄호 { ... }를 사용하여 여러 문장을 작성하는 경우에는 return을 명시적으로 사용해야 합니다.

결과 확인하기
6. 함수가 실행되었습니다.

07. 화살표 함수 : 익명 함수

익명 함수(Anonymous Function)를 화살표 함수(Arrow Function)로 표현하는 예제입니다.

{
    const func = () => {
        console.log("7. 함수가 실행되었습니다.");
    }
    func();
}

익명 함수를 화살표 함수로 변환하는 방법:
1. function 키워드 제거
2. 함수의 이름 제거: 화살표 함수는 항상 익명 함수이므로 이름을 제거합니다.
3. => 화살표 추가: 화살표 함수의 구문에서는 () => 형식으로 매개변수 부분을 표현합니다.
4. 중괄호 {}로 함수 본문 묶기: 함수의 본문을 중괄호 {} 내에 작성합니다.

결과 확인하기
7. 함수가 실행되었습니다.

08. 화살표 함수 : 매개변수 함수

화살표 함수로 매개변수를 포함하는 함수를 정의하고 호출하는 예제입니다.

{
    func = (str) => {
        console.log(str);
    }
    func("8. 함수가 실행되었습니다.");
}

매개변수를 화살표 함수로 표현하는 방법:
1. 화살표 함수로 매개변수 정의하기: () 안에 매개변수 이름을 적어줍니다.
str은 매개변수의 이름이며, 함수 내부에서 이 이름으로 전달된 값에 접근할 수 있습니다.
2. 함수 호출하기: 화살표 함수를 호출할 때는 함수 이름 뒤에 소괄호 ()를 사용하고, 필요한 경우 매개변수에 값을 전달합니다.
"실행되었습니다."라는 문자열을 func 함수로 전달하고, 이 문자열이 함수 내부에서 str 매개변수로 사용됩니다.

결과 확인하기
8. 함수가 실행되었습니다.

09. 화살표 함수 : 리턴값 함수

화살표 함수로 리턴값을 갖는 함수를 정의하고 호출하는 예제입니다.

{
    func = () => {
        return "9. 함수가 실행되었습니다.";
    }
    console.log(func());
}

리턴값을 갖는 화살표 함수를 표현하는 방법:
1. 화살표 함수로 리턴값 포함하기: return을 사용하여 함수의 실행 결과로 반환할 값을 지정합니다.
위 코드에서는 문자열 "9. 함수가 실행되었습니다."를 반환합니다. 2. 함수 호출과 반환값 사용: func 함수를 호출하고, 함수 내에서 정의한 문자열 "9. 함수가 실행되었습니다."를 반환합니다.
그리고 이 반환된 값이 console.log() 함수를 통해 콘솔에 출력됩니다.

결과 확인하기
9. 함수가 실행되었습니다.

10. 화살표 함수 : 익명함수 + 매개변수 + 리턴값 함수

설명

{
    //익명 함수
    const func = (str) => {
        return str;
    }
    console.log(func(10. 함수가 실행되었습니다.));

    //괄호 생략
    const func1 = str => {
        return str;
    }
    console.log(func1(10-2. 함수가 실행되었습니다.));

    //리턴 생략
    const func2 = srt => str;
    
    console.log(func2(10-3. 함수가 실행되었습니다.));

    //선언적(가독성X)
    func3 = srt => str;
    
    console.log(func3(10-4. 함수가 실행되었습니다.));
}

1. 익명 함수: 이 부분은 화살표 함수를 선언하고 func라는 변수에 할당하는 부분입니다.
str은 화살표 함수의 매개변수(parameter)로서, 함수가 호출될 때 외부에서 전달되는 값을 받습니다.
이 화살표 함수의 본문(body)입니다. 이 부분은 함수가 실행될 때 str 변수의 값을 반환합니다. 따라서 func 함수는 호출되면 전달된 str 값을 반환합니다.
2. 약식 표현: 괄호 생략: 매개변수가 하나인 경우에는 괄호 ()를 생략할 수 있습니다.
매개변수 str와 화살표 => 사이의 괄호 ()가 생략되어 있습니다.
하나의 매개변수를 받는 경우에만 괄호를 생략할 수 있습니다. 3. 약식 표현: 리턴 생략: return을 생략하고 값을 반환하려면 중괄호 {} 대신에 값을 직접 표현하면 됩니다. 4. 약식 표현: 선언적 (가독성이 떨어짐): 함수를 변수에 할당하면서 함수의 이름을 생략하는 형태입니다.
일반적으로 함수 이름을 생략하지 않고 명시적으로 변수에 할당해야 가독성이 좋습니다.

결과 확인하기
10. 함수가 실행되었습니다.
10-2. 함수가 실행되었습니다.
10-3. 함수가 실행되었습니다.
10-4. 함수가 실행되었습니다.

11. 함수 유형 : 함수와 매개변수를 이용한 형태

매개변수와 템플릿 리터럴을 이용한 형태의 함수 예제입니다.

{
    function func(num, str){
        console.log(`${num}. ${str}`);
    }
    func(11, "함수가 실행되었습니다.");
}

* 템플릿 리터럴: 문자열 생성 방법 중 하나로, 역따옴표 (``)로 둘러싸인 문자열입니다.
템플릿 리터럴을 사용하면 문자열 내에서 변수 또는 표현식을 ${} 안에 넣어 사용할 수 있습니다.
템플릿 리터럴을 사용하면 문자열을 보다 가독성 있고 편리하게 생성할 수 있으며, 변수나 표현식의 값을 문자열에 삽입하기 위해 별도의 문자열 연결(concatenation)을 사용하지 않아도 됩니다.

func 이라는 이름의 함수에 num과 str 속성을 매개변수로 사용하여 문자열을 출력합니다.
`${num}. ${str}`: 속성 num과 str의 값을 문자열 안에 넣습니다.

결과 확인하기
11. 함수가 실행되었습니다.

12. 함수 유형 : 함수와 변수를 이용한 형태

변수에 저장한 값을 연산자와 템플릿 리터럴을 이용하여 함수로 문자열을 출력하는 예제입니다.

{
    const num = 12;
    const str = "함수가 실행되었습니다.";

    function func(num, str){
        console.log(num +". " + str);
        console.log(`${num}. ${str}`);
    }
    func(num, str);
}

nun과 str 속성에 값을 각각 12와 "함수가 실행되었습니다." 저장합니다.
console.log(num +". " + str);: 연산자를 이용하여 문자열을 출력합니다.
console.log(`${num}. ${str}`); 템플릿 리터럴을 이용하여 문자열을 출력합니다.
func(num, str);: num과 str을 인수로 전달하여 func 함수를 실행합니다.

결과 확인하기
12. 함수가 실행되었습니다.
12. 함수가 실행되었습니다.

13. 함수 유형 : 함수와 배열을 이용한 형태

배열을 이용하여 함수로 문자열을 출력하는 예제입니다.

{
    const num = [13, 14];
    const str = ["함수가 실행되었습니다.", "함수가 실행되었습니다."];

    function func(num, str){
        console.log(`${num}. ${str}`);
    }
    func(num[0], str[0]);
    func(num[1], str[1]);
}

변수 num과 str에 배열과 각각 두 개의 요소를 생성합니다.
console.log(`${num}. ${str}`); 템플릿 리터럴을 이용하여 문자열을 출력합니다.
func(num[0], str[0]);: num의 배열 인덱스 0과 str의 배열 인덱스 0에 있는 값을 출력합니다.
func(num[1], str[1]);: num의 배열 인덱스 1과 str의 배열 인덱스 1에 있는 값을 출력합니다.

결과 확인하기
13. 함수가 실행되었습니다.
14. 함수가 실행되었습니다.

14. 함수 유형 : 함수와 객체를 이용한 형태

객체를 이용하여 함수로 문자열을 출력하는 예제입니다.

{
    const info = {
        num: 15,
        str: "함수가 실행되었습니다."
    }
    function func(num, str){
        console.log(`${num}. ${str}`);
    }
    func(info.num, info.str);
}

info 객체 안에 15 값을 가진 num 속성과 "함수가 실행되었습니다." 값을 가진 str 속성이 있습니다.
console.log(`${num}. ${str}`); 템플릿 리터럴을 이용하여 문자열을 출력합니다.
func(info.num, info.str);: info의 num 속성의 값과 str 속성의 값을 함수로 출력합니다.

결과 확인하기
15. 함수가 실행되었습니다.

15. 함수 유형 : 함수와 객체 및 배열을 이용한 형태

배열 안의 객체를 이용하여 함수로 문자열을 출력하는 예제입니다.

{
    const info = [
        { num: 16, str: "함수가 실행되었습니다."},
        { num: 17, str: "함수가 실행되었습니다."},
    ]
    function func(num, str){
        console.log(`${num}. ${str}`);
    }
    func(info[0].num, info[0].str);
    func(info[1].num, info[1].str);
}

info 배열 안에 2개의 객체를 가지고 있습니다.
첫번째 객체는 16 값을 가진 num 속성과 "함수가 실행되었습니다." 값을 가진 str 속성이 있습니다.
두번째 객체는 17 값을 가진 num 속성과 "함수가 실행되었습니다." 값을 가진 str 속성이 있습니다.
console.log(`${num}. ${str}`); 템플릿 리터럴을 이용하여 문자열을 출력합니다.
func(info[0].num, info[0].str);: info의 0번 인덱스의 num의 변수 값과 str의 변수 값을 출력합니다.
func(info[1].num, info[1].str);: info의 1번 인덱스의 num의 변수 값과 str의 변수 값을 출력합니다.

결과 확인하기
16. 함수가 실행되었습니다.
17. 함수가 실행되었습니다.

16. 함수 유형 : 객체 안에 함수를 이용한 형태

객체 안에 있는 함수를 이용하여 출력하는 예제입니다.

{
    const info = {
        num: 18,
        str: "함수가 실행되었습니다.",
        result: () => {
            console.log(`${info.num}. ${info.str}`);
        }
    }
    info.result();
}

react의 기본 문법으로 객체 안에 함수를 이용합니다.
result와 console.log(`${info.num}. ${info.str}`); 사이에 return false;가 생략되어 있습니다.
약식 표현으로 중괄호 생략하여 result: () => console.log(`${info.num}. ${info.str}`);로 나타낼 수 있습니다.
result는 info 객체의 num과 str 속성을 참조하여 템플릿 리터럴을 사용하여 문자열을 생성하고 콘솔에 출력합니다.
info.result();: info 객체의 result를 출력합니다.

결과 확인하기
18. 함수가 실행되었습니다.

17. 함수 유형 : 객체 생성자 함수

객체 생성자 함수와 this 키워드를 사용하여 객체를 생성하고 메서드를 정의한 예제입니다.

{
    function Func(num, str){
        this.num = num;
        this.str = str;
        this.result = () => {
            console.log(`${this.num}. ${this.str}`)
        }
    }

    const info1 = new Func(19, "함수가 실행되었습니다.");
    const info2 = new Func(20, "함수가 실행되었습니다.");

    info1.result();
    info2.result();
}

* this는 현재 실행 중인 함수 내에서 현재 객체를 참조하는 데 사용됩니다.
*객체 생성자 함수는 여러 개의 객체를 생성할 수 있으며, 이러한 객체는 동일한 속성과 메서드를 공유할 수 있습니다.
자바스크립트 함수 중 제일 많이 사용되며 react에서도 사용하는 함수입니다.

*인스턴스
인스턴스는 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)에서 사용되는 중요한 개념입니다.
인스턴스는 클래스(Class)를 기반으로 생성된 개별 객체를 가리킵니다.
- 클래스: 객체를 생성하기 위한 설계도나 템플릿입니다.
클래스는 객체가 가져야 할 속성과 메서드를 정의합니다.
- 인스턴스: 클래스를 기반으로 생성된 실제 객체를 나타냅니다.
인스턴스는 클래스의 속성과 메서드를 상속하며, 각 인스턴스는 고유한 데이터를 가질 수 있습니다.

예를 들어, "자동차"라는 클래스가 있다면 이 클래스를 기반으로 "벤츠 자동차"와 "토요타 자동차"와 같은 다양한 자동차 인스턴스를 생성할 수 있습니다.
각 인스턴스는 모델, 색상, 속도 등과 같은 자동차에 대한 고유한 속성을 가지며, 클래스에서 정의된 메서드(예: 가속, 제동)를 호출할 수 있습니다.

객체 생성자 함수에서는 보통 'Func'으로 설정합니다.
Func 함수는 num과 str 두 개의 매개변수를 받습니다.
this.num과 this.str는 객체의 속성으로 설정됩니다.
this.result는 객체의 메서드로, this를 사용하여 num과 str 속성을 참조하고 문자열을 출력합니다.

*인스턴트 생성
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 19와 "함수가 실행되었습니다." 값을 가진 객체 info1을 생성합니다.
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 20과 "함수가 실행되었습니다." 값을 가진 객체 info2를 생성합니다.

*호출
info1.result()와 info2.result(): 해당 객체의 result를 실행하여 num과 str 속성의 값을 출력합니다.

결과 확인하기
19. 함수가 실행되었습니다.
20. 함수가 실행되었습니다.

18. 함수 유형 : 프로토타입 함수

객체 생성자 함수의 효율을 높이기 위해 콘솔을 독립시킨 함수입니다.

{
    function Func(num, str){
        this.num = num;
        this.str = str;
    }

    Func.prototype.result = function(){
    console.log(`${this.num}. ${this.str}`);
    }

    const info1 = new Func(21, "함수가 실행되었습니다.");
    const info2 = new Func(22, "함수가 실행되었습니다.");

    info1.result();
    info2.result();    
}

*프로토타입 함수
콘솔이 함수 안에 있으면 콘솔을 출력할 때마다 함수가 실행되어야 하므로 처리 속도가 늘어나 효율성이 떨어진다.
이러한 문제를 해결하기 위해 콘솔을 함수 밖으로 빼서 함수를 매번 실행시키 않고 출력만 일어나도록 한다.
함수의 프로토타입에 추가된 속성과 메서드는 해당 함수로 생성된 모든 객체에서 공유됩니다.
따라서 모든 객체가 해당 메서드를 중복으로 가지지 않고 공유하여 메모리를 절약하고 효율성을 높일 수 있습니다.

*주의할 점: 화살표 함수는 객체 안에서는 this 인자를 받아올 수 있지만 객체 밖에서는 받아올 수 없습니다.

Func 함수는 num과 str 두 개의 매개변수를 받습니다.
this.num과 this.str는 객체의 속성으로 설정됩니다.
this.result는 객체의 메서드로, this를 사용하여 num과 str 속성을 참조하고 문자열을 출력합니다.
Func 함수의 프로토타입에 result라는 메서드를 추가합니다.
이 메서드는 객체의 num과 str 속성을 사용하여 문자열을 생성하고 콘솔에 출력합니다.
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 21과 "함수가 실행되었습니다." 값을 가진 객체 info1을 생성합니다.
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 22와 "함수가 실행되었습니다." 값을 가진 객체 info2를 생성합니다.
info1.result()와 info2.result(): 해당 객체의 result를 실행하여 num과 str 속성의 값을 출력합니다.

결과 확인하기
21. 함수가 실행되었습니다.
22. 함수가 실행되었습니다.

19. 함수 유형 : 객체 리터럴 함수

프로토타입 함수의 가독성을 높이기 위해 함수끼리 묶은 함수입니다.

{
    function Func(num, str){
        this.num = num;
        this.str = str;
    }
    
    Func.prototype = {
        result1 : function(){
            console.log(`${this.num}. ${this.str}`);
        },
        result2 : function(){
            console.log(`${this.num}. ${this.str}`);
        }
    }

    const info1 = new Func(23, "함수가 실행되었습니다.");
    const info2 = new Func(24, "함수가 실행되었습니다.");

    info1.result1();
    info2.result2();
}

객체 리터럴 함수는 프로토타입 함수의 객체 내에 함수를 할당한 함수입니다.
Func 함수는 num과 str 두 개의 매개변수를 받습니다.
this.num과 this.str는 객체의 속성으로 설정됩니다.
Func 함수의 프로토타입에 객체 리터럴을 사용하여 속성으로 result1과 result2 함수를 할당합니다
result1과 result2는 this를 사용하여 num과 str 속성을 참조하고 문자열을 출력합니다.
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 23과 "함수가 실행되었습니다." 값을 가진 객체 info1을 생성합니다.
new Func(...)를 사용하여 Func 객체 생성자 함수를 호출하여 num과 str 속성에 24와 "함수가 실행되었습니다." 값을 가진 객체 info2를 생성합니다.
info1.result1()와 info2.result2(): 해당 객체의 result1과 result2를 실행하여 num과 str 속성의 값을 출력합니다.

결과 확인하기
23. 함수가 실행되었습니다.
24. 함수가 실행되었습니다.

20. 함수 : 즉시실행 함수

즉시 실행 함수는 함수를 정의하고 즉시 실행합니다.
함수를 정의하고 즉시 실행하여 지역 범위(scope)를 만들 수 있으며, 변수의 스코프를 제어하거나 코드를 모듈화할 때 유용합니다.

{
    (function (){
        console.log("25. 함수가 실행되었습니다.");
    })();

    ( () => {
        console.log("26. 함수가 실행되었습니다.");
    })();
}

(function () { ... })로 함수를 둘러싸면 해당 함수가 함수 선언이 아닌 함수 표현식으로 취급되며, 이 함수는 함수 이름을 가지지 않습니다.
();는 함수 표현식을 호출하는 부분으로, 함수를 정의하자마자 즉시 실행됩니다. 이로 인해 "25. 함수가 실행되었습니다."라는 메시지가 출력됩니다.

결과 확인하기
25. 함수가 실행되었습니다.
26. 함수가 실행되었습니다.

21. 함수 : 파라미터 함수

매개변수를 활용한 예제입니다. 매개변수 함수와 똑같이 작동합니다.
매개변수의 기본값이 제공되므로 함수를 호출할 때 매개변수를 제공하지 않으면 기본값이 사용됩니다.

{
    function func(str = "27. 함수가 실행되었습니다."){
        console.log(str);
    }
    func();

    const func1 = (str = "28. 함수가 실행되었습니다.") => {
        console.log(str);
    }
    func1();
}

func 함수는 str이라는 매개변수를 가지며, 이 매개변수의 기본값은 "27. 함수가 실행되었습니다."입니다.
func();은 함수를 호출하고, 아무 매개변수도 전달하지 않으므로 기본값인 "27. 함수가 실행되었습니다."가 출력됩니다.
func1 함수는 str 매개변수를 가지고, 화살표 함수를 사용하며 기본값은 "28. 함수가 실행되었습니다."입니다.
func1();은 함수를 호출하고, 아무 매개변수도 전달하지 않으므로 기본값인 "28. 함수가 실행되었습니다."가 출력됩니다.

결과 확인하기
27. 함수가 실행되었습니다.
28. 함수가 실행되었습니다.

22. 함수 : 재귀 함수

반복문을 사용하여 지정된 횟수만큼 특정 메시지를 출력하는 것과 재귀 함수를 호출하면서 메시지를 출력하는 것을 비교한 예제입니다.
재귀 함수(recursive function)는 함수 내에서 자기 자신을 호출하여 문제나 반복 작업을 간결하게 표현하는 데 유용합니다.

{
    function func(num){
        for(let i=1; i<=num; i++){
            console.log("29. 함수가 실행되었습니다.");
        }
    }
    func(10);

    function func1(num){
        if(num < 1) return;

        console.log("30. 함수가 실행되었습니다.");
        func1(num - 1);
    }
    func1(10);
}

func 함수는 num이라는 매개변수를 받습니다.
for 반복문을 사용하여 1부터 num까지의 숫자 범위에서 "29. 함수가 실행되었습니다."라는 메시지를 반복 출력합니다.
func(10);은 func 함수를 호출하고, num 매개변수에 10을 전달하여 10번의 메시지 출력을 실행합니다.
func1 함수는 num이 1보다 작으면(즉, 0 이하일 때) 재귀 호출을 멈추고 함수를 빠져나옵니다.
그렇지 않으면 "30. 함수가 실행되었습니다."라는 메시지를 출력하고 func1 함수는 자기 자신을 호출하여 num을 1 감소시킵니다. 이로써 재귀 호출이 진행됩니다.
재귀 호출은 num이 0보다 작아질 때까지 계속되며, 각 호출마다 메시지가 출력됩니다.
func1(10);은 func1 함수를 최초로 호출하고, num 매개변수에 10을 전달하여 재귀적으로 함수를 호출하면서 10번의 메시지 출력을 실행합니다.

결과 확인하기
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
29. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.
30. 함수가 실행되었습니다.

23. 콜백 함수 : 다른 함수로 실행되는 함수

콜백함수는 다른 함수의 인자로써 넘겨진 후 특정 이벤트나 작업이 완료에 의해 호출되는 함수입니다.
자바스크립트에서 비동기 처리를 구현하는 가장 일반적인 방법 중 하나입니다.

{
    // 01 이벤트 콜백 함수
    function func(){
        console.log("31. 함수가 실행되었습니다.");
    }
    btn.addEventListerner("click", func);

    // 02 함수를 다른 함수의 인자로 전달
    function func1(){
        console.log("32. 함수가 실행되었습니다.");
    }
    function func2(callback){
        callback(); // func1();
    }
    func2(func1);
    
    // 03 반복문으로 콜백함수 만들기
    function func3(num){
        console.log(num + ". 함수가 실행되었습니다.");
    }

    // 함수를 하나씩 호출하기
    // func3(33);
    // func3(34);
    // func3(35);
    // func3(36);
    // func3(37);
    // func3(38);

    // for문으로 호출하기
    // for(let i=33; i<=38; i++){
    //     func3(i);
    // }

    function func4(callback){
        for(let i=33; i<=38; i++){
            callback(i);
        }
    }
    func4(func3);
}

01 이벤트 콜백 함수: func 함수는 클릭 이벤트가 발생했을 때 실행될 콜백 함수로 등록됩니다. 클릭 이벤트가 발생하면 "31. 함수가 실행되었습니다." 메시지가 출력됩니다.
02 함수를 다른 함수의 인자로 전달: func1과 func2가 동시에 발생되는 현상을 막고 func2의 실행이 끝난 후 func1이 실행하기 위해 사용합니다. func1을 func2의 인자로 전달합니다.
03 반복문으로 콜백함수 만들기: func3 함수는 숫자를 받아서 해당 숫자와 함께 메시지를 출력하는 콜백 함수입니다.
func4 함수는 콜백 함수 callback을 인자로 받아 반복문을 사용하여 33부터 38까지의 숫자를 func3 함수의 콜백으로 호출합니다.
따라서 func3 함수가 33부터 38까지의 숫자와 함께 실행됩니다.

결과 확인하기
33. 함수가 실행되었습니다.
34. 함수가 실행되었습니다.
35. 함수가 실행되었습니다.
36. 함수가 실행되었습니다.
37. 함수가 실행되었습니다.
38. 함수가 실행되었습니다.

24. 함수 : 비동기 함수 : 콜백 함수

사이트가 데이터를 불러올 때 오류가 생기는 것을 예방하기 위해 데이터를 불러오는 시간을 기다리고 난 뒤에 함수를 실행합니다.
콜백 함수가 중첩(nesting)되는 경우에는 코드의 가독성이 떨어지고, 콜백 지옥(callback hell)이라는 문제가 발생하기 때문에 fetch, SQL의 ASSIOC 등을 사용하기도 합니다.

{
    // 01 동기적인 함수 호출
    function func1(){
        console.log("39. 함수가 실행되었습니다.");
    }
    function func2(){
        console.log("40. 함수가 실행되었습니다.");
    }
    func1();
    func2();

    // 02 비동기적인 함수 호출
    function func3(){
        setTimeout(() => {
            console.log("41. 함수가 실행되었습니다.");
        }, 1000);
    }
    function func4(){
        console.log("42. 함수가 실행되었습니다.");
    }
    func3();
    func4();

    // 03 비동기적인 콜백 함수 호출
    function func5(callback){
        setTimeout(() => {
            console.log("43. 함수가 실행되었습니다.");
            callback();
        }, 1000);
    }
    function func6(){
        console.log("44. 함수가 실행되었습니다.");
    }
    func5(function(){
        func6();
    });

    // 콜백 지옥
    {
        function funcA(callback){
            setTimeout(() => {
                console.log("funcA가 실행되었습니다.");
                callback();
            }, 1000);
        }
        function funcB(callback){
            setTimeout(() => {
                console.log("funcB가 실행되었습니다.");
                callback();
            }, 1000);
        }
        function funcC(callback){
            setTimeout(() => {
                console.log("funcC가 실행되었습니다.");
                callback();
            }, 1000);
        }
        function funcD(){
            setTimeout(() => {
                console.log("funcD가 실행되었습니다.");
            }, 1000);
        }
        funcA(function(){
            funcB(function(){
                funcC(function(){
                    funcD();
                })
            })
        });
    }
}

1. 동기(Synchronous: 동시에 일어나는): 요청과 그 결과가 동시에 일어납니다. 순서에 맞춰 진행되므로 여러 가지 요청을 동시에 처리할 수 없습니다.
2. 비동기(Asynchronous: 동시에 일어나지 않는): 요청과 결과가 동시에 일어나지 않습니다. 요청을 보낸 후 결과와 관계없이 다음 동작을 실행할 수 있습니다.
01 동기적인 함수 호출: func1과 func2 함수는 동시에 순서대로 출력됩니다.
func1 함수가 실행을 마치고 나서 func2 함수가 실행됩니다.
02 비동기적인 함수 호출: func3과 func4 함수는 동시에 순서대로 출력되지 않습니다.
func3 함수는 setTimeout 함수를 사용하여 1초 후에 실행되도록 예약됩니다.
따라서 func3가 실행될 때 func4 함수가 이미 실행되었습니다. 이것이 비동기 호출의 특징입니다.
'41. 함수가 실행되었습니다.'가 1초 뒤에 나오므로 '42. 함수가 실행되었습니다.'를 실행한 후 출력됩니다.
03 비동기적인 콜백 함수 호출: func5과 func6 함수는 로딩을 기다린 후 순서대로 출력됩니다.
func5 함수는 비동기적으로 실행되며 1초 후에 func6 함수를 호출하는 콜백 함수를 실행합니다.
'43. 함수가 실행되었습니다.'를 실행한 후 1초 뒤에 '44. 함수가 실행되었습니다.'가 출력됩니다.
콜백 지옥은 여러 개의 비동기 함수를 연속적으로 호출하고, 각 함수가 이전 함수의 완료 시에 실행되어야 할 때 발생하는 상황을 나타냅니다.
위의 코드에서는 funcA가 실행된 후에 funcB가 실행되고, funcB가 실행된 후에 funcC가 실행되고, 마지막으로 funcD가 실행됩니다.
이런 중첩된 콜백 함수 호출은 코드를 복잡하고 어렵게 만들 수 있으므로 콜백 지옥을 피하기 위해 Promise, async/await와 같은 비동기 처리 패턴을 사용할 수 있습니다.

결과 확인하기
39. 함수가 실행되었습니다.
40. 함수가 실행되었습니다.
42. 함수가 실행되었습니다.
41. 함수가 실행되었습니다.
43. 함수가 실행되었습니다.
44. 함수가 실행되었습니다.
funcA가 실행되었습니다.
funcB가 실행되었습니다.
funcC가 실행되었습니다.
funcD가 실행되었습니다.

25. 함수 : 비동기 함수 : 프로미스

프로미스 함수는 비동기 작업을 처리하는 패턴 중 하나로, 콜백함수 보다 코드를 더 간결하고 이해하기 쉽게 만들어줍니다.

{
    let data = true;

    const func = new Promise((resolve, reject) => {
        if(data){
            resolve("45. 함수가 실행되었습니다.");
        } else {
            reject("45. 함수가 실행되지 않았습니다.");
        }
    });

    func
    .then(
        result => console.log(data)
    )
    .catch(
        error => console.log(error)
    )

    // 콜백지옥 -> 프로미스
    function funcA(){
        return new Promise((reslove) => {
            setTimeout(() => {
                console.log("funcA가 실행되었습니다.")
                reslove();
            }, 1000)
        })
    }
    function funcB(){
        return new Promise((reslove) => {
            setTimeout(() => {
                console.log("funcB가 실행되었습니다.")
                reslove();
            }, 1000)
        })
    }
    function funcC(){
        return new Promise((reslove) => {
            setTimeout(() => {
                console.log("funcC가 실행되었습니다.")
                reslove();
            }, 1000)
        })
    }
    function funcD(){
        return new Promise((reslove) => {
            setTimeout(() => {
                console.log("funcD가 실행되었습니다.")
                reslove();
            }, 1000)
        })
    }
    funcA()
        .then(funcB)
        .then(funcC)
        .then(funcD)
        .catch((error) => {
            console.log(error)
        })
}

func라는 프로미스 객체를 생성합니다. 이 프로미스는 비동기 작업을 나타내며, resolve 함수를 호출하여 성공적으로 작업을 완료하거나 reject 함수를 호출하여 실패했음을 나타냅니다.
then 메소드는 성공적으로 작업을 완료했을 때 호출됩니다.
catch 메소드는 작업이 실패했을 때 호출됩니다.
data가 true이므로 resolve 함수가 호출되고 "45. 함수가 실행되었습니다."가 출력됩니다.
프로미스를 사용하여 콜백 지옥을 해결:
funcA, funcB, funcC, 및 funcD는 각각 비동기 작업을 나타내는 프로미스를 반환하는 함수입니다.
각 함수는 resolve를 호출하여 작업을 성공적으로 완료합니다.
then 메소드를 사용하여 각 함수를 연결하고, 각 함수는 이전 함수의 완료 이후에 실행됩니다. 이를 통해 콜백 지옥(callback hell)을 피하고 코드를 읽기 쉽게 만듭니다.
각 함수는 setTimeout을 사용하여 1초 간격으로 실행됩니다. 따라서 "funcA가 실행되었습니다."부터 "funcD가 실행되었습니다."까지의 메시지가 1초 간격으로 출력됩니다.

결과 확인하기
45. 함수가 실행되었습니다.
funcA가 실행되었습니다.
funcB가 실행되었습니다.
funcC가 실행되었습니다.
funcD가 실행되었습니다.

26. 함수 : 비동기 함수 : asyne/await

async 함수는 비동기적 작업을 수행하고 await 키워드를 사용하여 비동기 작업이 완료될 때까지 대기하거나 결과를 반환하도록 만드는데 사용합니다.
코드를 보다 직관적으로 작성하고, 비동기 작업의 성공 및 실패에 대한 처리를 간편하게 수행할 수 있습니다.

{
    // 01
    function func(){
        console.log("46. 함수가 실행되었습니다.");
    }
    func();

    // 02
    async function func2(){
        console.log("47. 함수가 실행되었습니다.");
    }
    func2();

    // 03
    async function func3(){
        const result = await fetch("https://coconutpalmtreeisland.github.io/webs2024/json/gineungsaJC2011_05.json");
        const data = await result.json();
        console.log(data);
    }
    func3();

    // 04
    async function func4(){
            try {
                const result = await fetch("https://coconutpalmtreeisland.github.io/webs2024/json/gineungsaJC2011_05.json");
                const data = await result.json();
                console.log(data);
            } catch (error){
            console.log(error);
        }
        func4();
    }
}

01: func 함수는 동기적으로 실행되며, 호출 시점에 "46. 함수가 실행되었습니다." 메시지가 즉시 출력됩니다.
02: func2 함수는 async 키워드로 정의되었습니다. async 함수는 비동기적으로 실행됩니다.
그러나 함수 내부에서 어떤 비동기 작업도 수행하지 않으므로 호출 시점에 "47. 함수가 실행되었습니다." 메시지가 즉시 출력됩니다.
03: func3 함수는 async 키워드로 정의되었으며, 내부에서 fetch 함수를 사용하여 웹에서 JSON 데이터를 가져오고 처리합니다.
await를 사용하여 fetch 및 JSON 데이터 가져오기 작업이 완료될 때까지 대기합니다. 이를 통해 비동기 코드를 동기적으로 작성할 수 있으며, 데이터를 출력합니다.
04: func4 함수는 async 키워드로 정의되었으며, 데이터를 가져오는 중에 에러가 발생할 수 있기 때문에 try...catch 블록을 사용하여 에러를 처리합니다.
데이터를 가져오는 작업이 성공하면 데이터를 출력하고, 에러가 발생하면 에러 메시지를 출력합니다.

결과 확인하기
46. 함수가 실행되었습니다.
47. 함수가 실행되었습니다.

27. 함수 : 중첩 함수

{
    
    }
    


결과 확인하기

28. 함수 : 클로저

{
    
    }
    


결과 확인하기

29. 클래스 : 기본

{
    
    }
    


결과 확인하기

30. 클래스 : 상속

{
    
    }
    


결과 확인하기