자바스크립트 - 함수 올리기: 초보자 가이드

안녕하세요, 미래의 자바스크립트 마법사 여러분! 오늘 우리는 자바스크립트의 흥미로운 측면 중 하나를 탐구할 거예요. 초보자들이 종종 놀라는 함수 올리기(function hoisting)에 대해 이야기하겠습니다. 이 이름이 조금 수수께끼 같은 느낌이 들 수 있지만, 이 설명이 끝나면 프로처럼 함수를 올리는 법을 배울 거예요!

JavaScript - Function Hoisting

함수 올리기는 무엇인가요?

구체적인 내용을 알기 전에 간단한 정의를 시작으로 하겠습니다:

함수 올리기는 자바스크립트에서 함수 선언이 코드 실행 전에 스코프의 상단으로 이동되는 행위입니다.

이제 여러분이 떠올리는 것을 알고 있습니다: "하지만 선생님, 그게 무슨 말이죠?" 예제를 통해 설명해 보겠습니다.

예제 1: 마법처럼 나타나는 함수

sayHello(); // 이게 작동해요!

function sayHello() {
console.log("Hello, world!");
}

프로그래밍 초보자라면 이제 머리를 긁을 수도 있습니다. "정의되기 전에 함수를 호출할 수 있어요?"라는 질문이 드릴 수 있습니다. 여러분, 이게 바로 함수 올리기의 마법입니다!

이 예제에서 자바스크립트는 sayHello 함수 전체를 스코프의 상단으로 올립니다. 그래서 배경에서 코드가 이렇게 작성되는 것입니다:

function sayHello() {
console.log("Hello, world!");
}

sayHello(); // 이제 더 이해가 됩니다, 아닌가요?

예제 2: 두 함수의 이야기

다른 예제로 더 재미를 더해 보겠습니다:

greeting("John"); // 출력: "Hello, John!"
farewell("John"); // 오류: farewell is not a function

function greeting(name) {
console.log("Hello, " + name + "!");
}

var farewell = function(name) {
console.log("Goodbye, " + name + "!");
};

이 두 함수의 이야기에서 우리는 다른 행동을 보여줍니다. greeting 함수는 올리기 덕분에 정의 전에 호출할 수 있습니다. 하지만 불쌍한 farewell은 오류를 발생시킵니다. 왜냐하면 var farewell 선언만 올라갔지, 함수 할당은 올라가지 않았기 때문입니다.

함수 올리기의 규칙

이제 함수 올리기를 보았으니, 몇 가지 규칙을 정리해 보겠습니다:

  1. 함수 선언은 완전히 올라갑니다.
  2. 변수 선언은 올라가지만, 할당은 올라가지 않습니다.
  3. 함수 표현식은 올라가지 않습니다.

이 규칙들을 더 많은 예제를 통해 탐구해 보겠습니다!

예제 3: 선언 vs. 표현식

// 이게 작동해요
hello();

function hello() {
console.log("Hello from a function declaration!");
}

// 이게 작동하지 않습니다
goodbye(); // 오류: goodbye is not a function

var goodbye = function() {
console.log("Goodbye from a function expression!");
};

여기서 hello는 함수 선언이므로 완전히 올라갑니다. 하지만 goodbye는 함수 표현식이므로 var goodbye 선언만 올라가고, 함수 자체는 올라가지 않습니다.

자바스크립트 변수 올리기

이제 함수 올리기를 다루고 나서, 변수 올리기를 빠르게 살펴보겠습니다. 이는 이해해야 할 중요한 관련 개념입니다.

예제 4: 수수께끼 같은 정의되지 않음

console.log(x); // 출력: undefined
var x = 5;
console.log(x); // 출력: 5

이 예제에서 x의 선언은 올라갔지만 할당은 올라가지 않았기 때문에, 첫 console.logundefined를 출력합니다. 두 번째 console.log는 할당된 값을 출력합니다.

예제 5: Let과 Const - 새로운 아이들

console.log(a); // 오류: Cannot access 'a' before initialization
let a = 10;

console.log(b); // 오류: Cannot access 'b' before initialization
const b = 20;

ES6에서 도입된 letconst는 새로운 행동을 가지고 있습니다. 이 선언은 올라갔지만 초기화되지 않았기 때문에, 선언 전에 변수에 접근할 수 없는 "시간적 사막(temporal dead zone)"이 생성됩니다.

실질적인 의미와 좋은 관행

이제 올리기를 이해했으니, 우리는 어떤 의미를 가지고 있을까요?

  1. 항상 스코프의 상단에서 변수를 선언하세요. 이렇게 하면 코드가 더 명확해지고 예상치 못한 행동을 방지할 수 있습니다.
  2. 전체 코드에서 사용할 함수는 함수 선언을 사용하세요. 그들의 올리기 행동이 유리할 수 있습니다.
  3. 함수 표현식에 주의하세요. 그들은 올라가지 않으므로 주의가 필요합니다.
  4. 의심이 든다면, 선언과 초기화를 함께 작성하세요. 변수 값에 대한 모호성을 제거할 수 있습니다.
  5. letconst를 사용하는 것을 고려하세요. 그들은 더 예측 가능한 스코핑 행동을 제공합니다.

다음 표는 다양한 선언 유형의 올리기 행동을 요약합니다:

선언 유형 올라감 초기화됨
함수 선언
var 정의되지 않음
let 아님 (TDZ)
const 아님 (TDZ)
함수 표현식 아님 아님

결론

그렇습니다, 저의 용맹한 프로그래머 여러분! 자바스크립트의 함수 올리기의 미스터리를 풀어냈습니다. 이 개념을 이해하는 것은 규칙을 알고 더 깨끗하고 예측 가능한 코드를 작성하는 것에 관한 것입니다.

자바스크립트 여정을 계속하면서 많은 흥미롭고 때로는 혼란스러운 기능을 만나게 될 것입니다. 하지만 걱정하지 마세요! 새로운 것을 배울 때마다 자바스크립트 닌자에 한 걸음 더 가까워집니다.

계속 연습하고, 계속 코딩하고, 가장 중요한 것은 질문을 계속하세요. 결국, 물어보지 않은 질문은 바보 같은 질문입니다!

다음 번에 만날 때까지, 행복하게 코딩하세요!

Credits: Image by storyset