7장: JavaScript 고급 개념

JavaScript의 기본 문법을 익힌 후에는 고급 개념을 이해하는 것이 중요합니다. 이 장에서는 스코프와 클로저, 호이스팅, 콜백 함수와 비동기 처리에 대해 알아보겠습니다.


#### 스코프와 클로저


##### 스코프


스코프는 변수나 함수가 접근할 수 있는 유효 범위를 의미합니다. JavaScript에서는 함수 스코프와 블록 스코프가 있습니다.


- **전역 스코프**: 코드 어디서든 접근 가능한 범위입니다.

- **함수 스코프**: 함수 내부에서만 접근 가능한 범위입니다.

- **블록 스코프**: `let`과 `const`로 선언된 변수는 블록(`{}`) 내에서만 접근 가능합니다.


let globalVar = "global";


function myFunction() {

    let localVar = "local";

    console.log(globalVar); // "global"

    console.log(localVar);  // "local"

}


myFunction();

console.log(globalVar); // "global"

console.log(localVar);  // Uncaught ReferenceError: localVar is not defined


##### 클로저


클로저는 함수가 생성될 때의 스코프를 기억하는 함수입니다. 클로저는 함수 내부에 선언된 함수가 외부 함수의 변수에 접근할 수 있게 합니다.


function outerFunction() {

    let outerVar = "I'm outside!";


    function innerFunction() {

        console.log(outerVar); // "I'm outside!"

    }


    return innerFunction;

}


let inner = outerFunction();

inner();


위 예제에서 `innerFunction`은 `outerVar`에 접근할 수 있습니다. 이는 클로저의 특성 덕분입니다.


#### 호이스팅


호이스팅은 JavaScript의 변수와 함수 선언이 해당 스코프의 최상단으로 끌어올려지는 특성입니다. 다만, 변수의 초기화는 호이스팅되지 않습니다.


console.log(hoistedVar); // undefined

var hoistedVar = "I'm hoisted!";


hoistedFunction(); // "This function is hoisted!"

function hoistedFunction() {

    console.log("This function is hoisted!");

}


`let`과 `const`로 선언된 변수는 호이스팅되지만 초기화 전에 접근할 수 없습니다.


console.log(notHoisted); // Uncaught ReferenceError: Cannot access 'notHoisted' before initialization

let notHoisted = "This is not hoisted!";


#### 콜백 함수와 비동기 처리


##### 콜백 함수


콜백 함수는 다른 함수의 인수로 전달되어 실행되는 함수입니다. 비동기 작업이 완료된 후 실행할 코드를 지정할 때 자주 사용됩니다.


function fetchData(callback) {

    setTimeout(() => {

        callback("Data fetched!");

    }, 2000);

}


function displayData(data) {

    console.log(data);

}


fetchData(displayData); // "Data fetched!" (2초 후 출력)


##### 프로미스 (Promise)


프로미스는 비동기 작업의 완료 또는 실패를 나타내는 객체입니다. `then`과 `catch` 메서드를 사용하여 결과를 처리합니다.


let promise = new Promise((resolve, reject) => {

    let success = true;


    setTimeout(() => {

        if (success) {

            resolve("Promise fulfilled!");

        } else {

            reject("Promise rejected!");

        }

    }, 2000);

});


promise

    .then((message) => {

        console.log(message); // "Promise fulfilled!" (2초 후 출력)

    })

    .catch((error) => {

        console.error(error);

    });


##### async/await


`async`와 `await` 키워드는 프로미스를 더 쉽게 사용할 수 있게 합니다. `async` 함수는 항상 프로미스를 반환하며, `await` 키워드는 프로미스가 해결될 때까지 기다립니다.


async function fetchData() {

    let data = await new Promise((resolve) => {

        setTimeout(() => {

            resolve("Data fetched with async/await!");

        }, 2000);

    });


    console.log(data);

}


fetchData(); // "Data fetched with async/await!" (2초 후 출력)


위 예제에서 `await` 키워드는 프로미스가 해결될 때까지 함수 실행을 일시 중지합니다. 이는 비동기 코드를 동기식 코드처럼 작성할 수 있게 합니다.


이 장에서는 JavaScript의 고급 개념인 스코프와 클로저, 호이스팅, 콜백 함수와 비동기 처리에 대해 배웠습니다. 이러한 개념을 이해하면 더 복잡한 JavaScript 코드를 작성하고 디버깅하는 데 도움이 됩니다. 다음 장에서는 JavaScript와 웹 API에 대해 알아보겠습니다.

댓글