자바스크립트에서 여태 우리가 한 건
변수, 조건문, 반복문 등
전부 "값을 다루는 도구"였다.
이제는 행동을 묶는 함수를 배울 차례다.
함수는 단순히 "코드 묶음"이 아니다.
구조적으로 보면
입력 → 처리 → 출력
이 구조를 이름 붙여서 재사용 가능하게 만든 것이 함수다.
예를 들어:
function add(a, b) {
return a + b;
}
이건 단순 계산이 아니라
"두 수를 더하는 행동"을 추상화한 것이다.
함수가 중요한 이유는 단순히
"코드를 줄이기 위해서"가 아니다.
함수는 복잡한 행동을 하나의 이름으로 치환하는 장치로
행동을 추상화하는 게 키포인트다.
자바스크립트에서 함수 만드는 방법은 크게 두 가지다.
function greet(name) {
console.log("안녕하세요, " + name);
}
이름이 필수고, 선언 전에 호출이 가능한데,
무엇보다 호이스팅이 되는 가장 큰 특징이 있다.
호이스팅은 자바스크립트가 코드를 실행하기 전에
선언을 먼저 메모리에 올리는 동작이다
자바스크립트는 코드를 위에서 아래로 실행하지만,
그 전에 한 번 "뭐가 선언되어 있는지" 먼저 훑는다.
이 과정에서 함수 선언문은 통째로 메모리에 올라간다.
greet("홍길동"); // 안녕하세요, 홍길동
function greet(name) {
console.log("안녕하세요, " + name);
}
함수보다 위에서 호출했는데도 에러가 안 난다.
실제로는 자바스크립트가 실행 전에 함수 선언을 메모리에 올려둬서 그렇다.
const greet =function(name) {
console.log("안녕하세요, " + name);
};
표현식은 변수 선언은 호이스팅 되지만,
함수 값은 실행 시점에 할당되므로 선언 전에 호출할 수 없다.
greet("홍길동"); // X TypeError (아직 초기화 안 됨)
const greet = function(name) {
console.log("안녕하세요, " + name);
};
| 구분 | 선언문 | 표현식 |
|---|---|---|
| 호이스팅 | O | X |
| 형태 | function name() {} | const name = function() {} |
| 호출 시점 | 선언 전 가능 | 선언 후 가능 |
둘의 차이를 알아봤으니,
이젠 언제 무엇을 쓰는지 구별할 차례다.
정리해서
선언문은 "미리 정의된 함수"이고,
표현식은 "변수에 담긴 함수 값"이다.
이 차이가 나중에
콜백, 고차 함수, Arrow Function으로 이어진다.
많은 사람들이 return이 값을 돌려주는 것이라고 이해한다.
하지만 return의 더 중요한 역할은 함수의 실행을 즉시 종료시키는 것이다.
function add(a, b) {
return a + b;
}
const result = add(10, 20);
console.log(result); // 30
여기서 return은
계산 결과를 "밖으로 내보낸다."
return은 그 즉시 함수를 종료시킨다.
function test(){
console.log("A");
return;
console.log("B");
}
test();
위와 같은 코드의 출력값은 "A"가 된다.
B는 실행되지 않는다.
return을 만나 함수 실행이 끝났기 때문이다.
이걸 이해하면
Early Return 패턴이 자연스럽게 이해된다.
function processUser(user) {
if (user) {
if (user.age >= 18) {
if (user.verified) {
return "처리 완료";
}
}
}
}
위 코드는 성공 케이스를 제일 안쪽에 뒀기 때문에
조건이 참일 때 들여쓰기 3단까지 계속 들어간다.
"성공 조건을 찾으러 들어가는 구조"라고 할 수 있다.
이런 코드에 Early Return 패턴을 채택하면
굉장히 깔끔하게 명확하게 바꿔줄 수 있다.
function processUser(user) {
if (!user) return "사용자 없음";
if (user.age < 18) return "미성년자";
if (!user.verified) return "인증 필요";
return "처리 완료";
}
Early Return 패턴을 통해서
실패 조건을 먼저 잘라내서 통과한 경우만 아래로 내려간다.
들여쓰기도 0~1단으로 굉장히 깔끔한 형태를 갖춘다.
"이상한 케이스를 먼저 제거하는 구조"라고 할 수 있다.
핵심은
return은 값을 반환하는 도구이면서
동시에 흐름 제어 장치라는 것이다.
조건문과 함께 쓰일 때
코드 구조를 깔끔하게 만든다.
function greet() {
console.log("안녕하세요");
}
const result = greet();
console.log(result);
위 함웃에는 실행을 종료시키는 return이 없다.
그렇다면 결과값은
안녕하세요
undefined
위와 같이 undefined를 출력한다.
머리말에서 지금까지 우린 값을 다루는 도구를 배웠다고 언급했다.
숫자, 문자열, 배열, 객체, 모두가 값이다.
그런데 자바스크립트에서는 함수도 값이다.
변수에 담을 수 있고
다른 함수에 전달할 수 있고
반환할 수 있는 것
이 세 가지가 충족되면 일급 객체라고 부르며,
쉽게 말해 값처럼 다룰 수 있는 대상을 말한다.
const greet = function() {
console.log("안녕하세요");
};
greet();
여기서 greet는 문자열도 숫자도 아니고
함수 자체가 값으로 변수에 저장된 것이다.
function runTwice(callback) {
callback();
callback();
}
runTwice(function() {
console.log("실행!");
});
위 코드에서는 함수가 또 다른 함수의 인자로 전달된다.
이렇게 전달된 함수를 콜백 함수라고 한다.
function createMultiplier(multiplier) {
return function(num) {
return num * multiplier;
};
}
const double = createMultiplier(2);
console.log(double(5)); // 10
위 코드는 createMultiplier() 함수가
function() 함수를 반환한다.
이처럼 함수는 함수를 반환해낼 수 있다.
함수를 값으로 취급한다는 말은
행동을 변수처럼 다룬다는 말이 된다.
즉, 행동을 변수처럼 다룰 수 있기 때문에
조건에 따라 다른 동작을 선택하거나,
나중에 실행할 행동을 미리 정의해둘 수 있다.
함수는 값이기 때문에
다른 함수에 전달할 수 있다.
이렇게 인자로 전달되는 함수를 콜백 함수라고 한다.
사실 아직 콜백함수를 딥하게 들어가진 않았지만,
앞으로도 꾸준히 볼 친구라고 배웠다.
그래서 동기 콜백, 비동기 두 예시만 가져왔다.
function runTwice(callback) {
callback();
callback();
}
runTwice(function() {
console.log("실행!");
});
setTimeout(function() {
console.log("3초 후 실행");
}, 3000);
동기든 비동기든 핵심은
"나중에 실행할 행동을 미리 넘겨둔다" 는 것이다.
자바스크립트에서 this는
함수를 호출한 객체를 가리키는 키워드다.
예를 들어:
const person = {
name: "홍길동",
greet: function() {
console.log(this.name);
}
};
person.greet();
여기서 this는 person 객체를 가리킨다.
그래서 결과는 홍길동이 된다.
const person = {
name: "홍길동",
greet: function() {
setTimeout(function() {
console.log(this.name);
}, 1000);
}
};
person.greet();
여기서 this는 person이 아니라
전역 객체(window)를 가리키게 된다.
그래서 undefined가 출력된다.
ES6 이후 자바스크립트에서는
함수를 더 간결하게 작성할 수 있는
Arrow Function(화살표 함수) 문법이 도입되었다.
기존 함수 표현식과 비교하면
문법이 간결해지고 콜백에서 많이 사용된다는 특징이 있다.
기존 함수 표현식
const add = function(a, b) {
return a + b;
};
Arrow Function
const add = (a, b) => {
return a + b;
};
동작은 같지만
Arrow Function은 더 간결한 형태로 작성할 수 있다.
return만 있는 경우에는
중괄호와 return을 생략할 수 있다.
const add = (a, b) => a + b;
매개변수가 하나라면 괄호를 생략할 수 있다.
const square = x => x * x;
하지만 두 개 이상이면 괄호가 필요하다.
Arrow Function은 특히
콜백 함수에서 자주 사용된다.
setTimeout(() => {
console.log("3초 후 실행");
}, 3000);
이처럼 짧은 동작을 전달할 때
Arrow Function이 많이 쓰인다.
Arrow Function은 일반 함수와 달리
자신만의 this를 가지지 않는다.
대신 바깥 함수의 this를 그대로 사용한다.
const person = {
name: "홍길동",
greet: function() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
person.greet();
이 경우 this는
바깥 함수의 this인 person을 그대로 사용한다.
그래서 정상적으로 홍길동이 출력된다.
함수는 단순한 코드 묶음이 아니라
행동을 하나의 이름으로 묶는 추상화 도구다.
자바 스크립트의 함수는
입력 → 처리 → 출력 구조로 동작한다.
return은 값을 반환하기도 하지만
함수의 실행 흐름을 종료시키는 역할도 한다.
자바스크립트에서 함수는
값처럼 다룰 수 있는 일급 객체다.
함수는 변수에 저장할 수 있고
다른 함수에 전달할 수 있으며
함수의 반환값으로도 사용할 수 있다.
함수가 다른 함수에 전달되면
콜백함수로 사용된다.
this는 함수를 호출한 객체에 따라 달라지는 키워드다.
Arrow Function은
자신만의 this를 만들지 않고 바깥 this를 사용한다.