자바스크립트 기초 #4 함수
#3 제어 흐름 에서 분기와 반복을 봤으니, 이번엔 재사용 가능한 코드 단위를 만드는 도구 — 자바스크립트의 함수를 다룹니다.
함수 선언 (Function Declaration) #
가장 전통적인 형태.
function add(a, b) {
return a + b;
}
add(2, 3); // 5
키워드 function으로 시작하고 이름을 가집니다. 가장 큰 특징은 호이스팅(잠시 뒤 설명) 이라 코드 어디서 호출해도 동작한다는 점입니다.
함수 표현식 (Function Expression) #
함수를 값으로 다루는 형태.
const add = function(a, b) {
return a + b;
};
add(2, 3); // 5
function 키워드가 식의 오른쪽에 있습니다. 변수 add에 함수가 들어간 거고, 변수와 같은 규칙으로 동작합니다(블록 스코프, 호이스팅 안 됨).
화살표 함수 (Arrow Function) #
ES2015에 추가된 짧은 형태. 콜백처럼 짧은 함수에 매우 자주 씁니다.
const add = (a, b) => a + b;
const square = (n) => n * n;
const greet = (name) => {
console.log(`안녕, ${name}!`);
};
add(2, 3); // 5
square(5); // 25
greet('커티스');문법 요약:
- 본문이 표현식 하나면
{ return ... }생략 가능 - 매개변수가 하나면 괄호 생략 가능 (
n => n * 2) - 매개변수가 0개거나 둘 이상이면 괄호 필수
화살표 함수와 일반 함수의 차이 — this
#
가장 큰 차이는 this의 동작입니다. 일반 함수는 호출 방식에 따라 this가 달라지지만, 화살표 함수는 선언된 위치의 this를 그대로 가져갑니다.
const obj = {
name: '커티스',
greetLater() {
setTimeout(function() {
console.log(this.name); // undefined (this가 obj가 아님)
}, 100);
},
greetLaterArrow() {
setTimeout(() => {
console.log(this.name); // '커티스' (바깥 this 유지)
}, 100);
},
};이 차이 때문에 콜백 함수는 화살표 함수, 객체 메서드는 일반 함수 또는 메서드 단축 문법이 흔한 컨벤션입니다. this는 고급 시리즈에서 깊이 다룹니다.
어떤 걸 언제 쓰나요? #
실무에서 가장 흔한 가이드:
- 함수 선언 — 모듈 최상위에 두는 의미 있는 함수 (
function calculate(...)) - 화살표 함수 — 짧은 콜백, 변환, 계산 (
map((x) => x * 2)) - 함수 표현식 — 화살표가 없던 시절의 흔적. 새 코드에서는 거의 안 씀
이 시리즈도 그 가이드를 따릅니다.
매개변수 — 기본값 #
매개변수에 기본값을 줄 수 있습니다.
function greet(name = '익명') {
console.log(`안녕, ${name}!`);
}
greet(); // 안녕, 익명!
greet('커티스'); // 안녕, 커티스!
greet(undefined); // 안녕, 익명! ← undefined도 기본값 발동
greet(null); // 안녕, null! ← null은 그대로
undefined는 기본값을 발동시키지만 null은 그대로 전달됩니다. “값이 정해지지 않음"의 두 가지 의미(#2)가 여기서 다른 동작을 만듭니다.
매개변수 — 가변 인자 (...rest)
#
인자를 몇 개 받을지 모를 때 ...으로 모을 수 있습니다.
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
sum(1, 2); // 3
sum(1, 2, 3, 4, 5); // 15
sum(); // 0
...numbers는 나머지 인자들을 배열로 모읍니다. 마지막 매개변수에만 쓸 수 있습니다.
일반 인자와 함께 #
function logCall(label, ...args) {
console.log(`[${label}]`, ...args);
}
logCall('debug', 1, 2, 3);
// [debug] 1 2 3
호출하는 쪽의 ...args는 펼치기(spread) 라고 부릅니다. 같은 ... 문법이지만 위치에 따라 의미가 달라요. 이 둘은 #5 객체와 배열 에서 다시 다룹니다.
반환 — return
#
함수가 값을 돌려주는 키워드.
function double(n) {
return n * 2;
}
double(5); // 10
return을 만나면 함수가 즉시 종료됩니다. 그 뒤의 코드는 실행되지 않습니다.
function describe(n) {
if (n === 0) return '영';
if (n < 0) return '음수';
return '양수';
}이른 반환은 들여쓰기를 줄이고 흐름을 직선화합니다. 깊은 if/else보다 거의 항상 읽기 좋습니다. 추천하는 패턴입니다.
return이 없으면 undefined
#
function silent() {
console.log('했음');
// return 없음
}
const result = silent();
console.log(result); // undefined
자바스크립트의 모든 함수는 무언가를 반환합니다. 명시적 return이 없으면 undefined가 자동으로 돌아옵니다.
호이스팅 — 함수 선언의 특수성 #
자바스크립트가 코드를 실행하기 전에, 함수 선언과 변수 선언을 미리 위로 끌어올리는 동작을 호이스팅(hoisting)이라 부릅니다.
함수 선언은 호이스팅이 완전히 일어나서, 코드 어디서든 호출할 수 있습니다.
console.log(add(2, 3)); // 5 — 선언 위에서 호출했는데 동작
function add(a, b) {
return a + b;
}반면 함수 표현식이나 화살표 함수는 변수라서, 선언 줄 이전에 쓰면 에러가 납니다.
console.log(add(2, 3)); // ✗ ReferenceError
const add = (a, b) => a + b;대부분의 코드는 사용 전에 선언하기 때문에 호이스팅을 의식할 일은 적습니다. 다만 함수 선언만 끌어올려진다는 사실은 옛 코드를 읽을 때 종종 만나요.
클로저 — 함수가 자기 환경을 들고 다님 #
함수의 강력한 특성 한 가지를 미리 봅시다.
function createCounter() {
let count = 0;
return function() {
count = count + 1;
return count;
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
counter(); // 3
createCounter가 끝났는데도 그 안의 count가 살아 있고 함수에 의해 기억됩니다. 이렇게 함수가 자기가 만들어진 환경(스코프)을 끌고 다니는 동작을 클로저라 부릅니다.
클로저는 자바스크립트의 가장 중요한 개념 중 하나로, 콜백,이벤트 핸들러,hook의 동작 모두에 들어 있습니다. 고급 시리즈에서 본격적으로 다룹니다. 지금은 “함수가 자기 변수를 기억한다” 만 잡아 두세요.
즉시 실행 함수 (IIFE) — 옛 패턴 #
옛 코드에서 자주 보이는 모양 한 가지.
(function() {
console.log('만들자마자 실행');
})();함수를 정의하자마자 호출하는 패턴입니다. 옛날에는 모듈이 없어서 변수 스코프를 격리하기 위한 트릭으로 썼습니다. 모듈이 있는 지금은 거의 쓰지 않습니다. 옛 자료를 읽다가 만나면 “옛날 모듈 흉내” 정도로 알면 됩니다.
마무리 #
이번 글에서 정리한 내용:
- 함수 정의 세 가지 — 선언 / 표현식 / 화살표
- 화살표 함수의 가장 큰 차이는
this가 바깥에서 들어옴 - 의미 있는 함수는 선언, 짧은 콜백은 화살표
- 기본값 매개변수 —
undefined면 발동,null은 그대로 ...rest로 가변 인자 모으기- 이른 반환(early return) 으로 흐름 직선화
- 함수 선언만 호이스팅 — 표현식은 변수 규칙
- 클로저: 함수가 자기 환경을 기억
다음 글(#5 객체와 배열)에서는 자바스크립트의 두 핵심 자료구조 — 객체와 배열의 기본 사용법, 그리고 spread/디스트럭처링 같은 모던 문법을 다룹니다.