JavaScript 익명 함수와 화살표 함수 완전 정복
목차
함수 선언의 세 가지 방법
JavaScript에서 함수를 만드는 방법은 크게 세 가지가 있습니다:
1. 함수 선언식 (Function Declaration)
function greet(name) {
return "안녕하세요, " + name + "님!";
}
console.log(greet("홍길동")); // "안녕하세요, 홍길동님!"
특징:
- 함수 이름이 필수
- 호이스팅(hoisting) 됨 (코드 실행 전에 메모리에 등록됨)
- 어디서든 호출 가능
2. 함수 표현식 (Function Expression) - 익명 함수
const greet = function(name) {
return "안녕하세요, " + name + "님!";
};
console.log(greet("홍길동")); // "안녕하세요, 홍길동님!"
특징:
- 함수 이름이 없음 (익명 함수)
- 변수에 할당됨
- 호이스팅 안 됨 (선언 전에 호출 불가)
3. 화살표 함수 (Arrow Function)
const greet = (name) => {
return "안녕하세요, " + name + "님!";
};
console.log(greet("홍길동")); // "안녕하세요, 홍길동님!"
특징:
function키워드 대신=>사용- 더 간결한 문법
this바인딩이 다름
익명 함수 (Anonymous Function)
정의
이름이 없는 함수를 익명 함수(Anonymous Function)라고 합니다. 함수 표현식에서 함수 이름을 생략한 형태입니다.
기본 문법
const 함수명 = function(매개변수) {
// 함수 내용
return 반환값;
};
예제 1: 기본 사용
// 익명 함수를 변수에 할당
const add = function(a, b) {
return a + b;
};
console.log(add(3, 5)); // 8
예제 2: 즉시 실행 함수 (IIFE)
// 함수를 정의하고 바로 실행
(function() {
console.log("즉시 실행!");
})();
// 매개변수 전달
(function(name) {
console.log("안녕하세요, " + name);
})("홍길동");
예제 3: 콜백 함수로 사용
// 배열의 forEach 메서드에 익명 함수 전달
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(num) {
console.log(num * 2);
});
// 출력: 2, 4, 6, 8, 10
// setTimeout에 익명 함수 전달
setTimeout(function() {
console.log("3초 후 실행!");
}, 3000);
예제 4: 이벤트 리스너에 사용
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log('버튼이 클릭되었습니다!');
});
예제 5: map, filter, reduce에 사용
const numbers = [1, 2, 3, 4, 5];
// map: 각 요소를 변환
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]
// filter: 조건에 맞는 요소만 필터링
const evens = numbers.filter(function(num) {
return num % 2 === 0;
});
console.log(evens); // [2, 4]
// reduce: 배열을 하나의 값으로 축약
const sum = numbers.reduce(function(acc, num) {
return acc + num;
}, 0);
console.log(sum); // 15
화살표 함수 (Arrow Function)
정의
ES6(ES2015)에서 도입된 더 간결한 함수 문법입니다. function 키워드 대신 => 화살표를 사용합니다.
기본 문법
// 기본 형태
const 함수명 = (매개변수) => {
return 반환값;
};
// 매개변수가 하나일 때 괄호 생략 가능
const 함수명 = 매개변수 => {
return 반환값;
};
// 단일 표현식일 때 return과 중괄호 생략 가능
const 함수명 = (매개변수) => 반환값;
예제 1: 기본 사용
// 일반 함수
const add1 = function(a, b) {
return a + b;
};
// 화살표 함수
const add2 = (a, b) => {
return a + b;
};
// 화살표 함수 (간단한 형태)
const add3 = (a, b) => a + b;
console.log(add1(3, 5)); // 8
console.log(add2(3, 5)); // 8
console.log(add3(3, 5)); // 8
예제 2: 매개변수가 하나일 때
// 괄호 생략 가능
const square1 = (x) => x * x;
const square2 = x => x * x; // 괄호 생략
console.log(square1(5)); // 25
console.log(square2(5)); // 25
예제 3: 매개변수가 없을 때
// 괄호 필수
const greet1 = () => "안녕하세요!";
const greet2 = () => {
return "안녕하세요!";
};
console.log(greet1()); // "안녕하세요!"
console.log(greet2()); // "안녕하세요!"
예제 4: 객체 반환 시 주의
// 객체를 반환할 때는 괄호로 감싸야 함
const createUser1 = (name, age) => {
return { name: name, age: age };
};
// 간단한 형태 (괄호 필수!)
const createUser2 = (name, age) => ({ name: name, age: age });
console.log(createUser1("홍길동", 25)); // {name: "홍길동", age: 25}
console.log(createUser2("홍길동", 25)); // {name: "홍길동", age: 25}
예제 5: 배열 메서드와 함께 사용
const numbers = [1, 2, 3, 4, 5];
// map
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
// reduce
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// find
const found = numbers.find(num => num > 3);
console.log(found); // 4
예제 6: 이벤트 리스너에 사용
const button = document.querySelector('button');
// 화살표 함수 사용
button.addEventListener('click', () => {
console.log('버튼이 클릭되었습니다!');
});
// 매개변수 사용
button.addEventListener('click', (event) => {
console.log('이벤트:', event);
});
예제 7: setTimeout, setInterval에 사용
// setTimeout
setTimeout(() => {
console.log("3초 후 실행!");
}, 3000);
// setInterval
let count = 0;
const timer = setInterval(() => {
count++;
console.log(count);
if(count >= 5) {
clearInterval(timer);
}
}, 1000);
익명 함수 vs 화살표 함수 비교
1. 문법 비교
// 익명 함수
const func1 = function(a, b) {
return a + b;
};
// 화살표 함수
const func2 = (a, b) => a + b;
2. this 바인딩 차이 ⭐ 중요!
const obj = {
name: "홍길동",
// 익명 함수: this가 obj를 가리킴
greet1: function() {
console.log("안녕하세요, " + this.name);
},
// 화살표 함수: this가 상위 스코프를 가리킴 (여기서는 window/global)
greet2: () => {
console.log("안녕하세요, " + this.name); // undefined 또는 에러
}
};
obj.greet1(); // "안녕하세요, 홍길동"
obj.greet2(); // "안녕하세요, undefined"
3. 이벤트 리스너에서의 this
const button = document.querySelector('button');
// 익명 함수: this가 button 요소를 가리킴
button.addEventListener('click', function() {
console.log(this); // <button> 요소
console.log(this.textContent); // 버튼의 텍스트
});
// 화살표 함수: this가 상위 스코프를 가리킴
button.addEventListener('click', () => {
console.log(this); // window 객체
console.log(this.textContent); // undefined
});
4. 생성자 함수로 사용 불가
// 익명 함수: 생성자 함수로 사용 가능
const Person1 = function(name) {
this.name = name;
};
const person1 = new Person1("홍길동"); // 가능
// 화살표 함수: 생성자 함수로 사용 불가
const Person2 = (name) => {
this.name = name;
};
const person2 = new Person2("홍길동"); // 에러!
5. arguments 객체 사용 불가
// 익명 함수: arguments 객체 사용 가능
const func1 = function() {
console.log(arguments); // 전달된 모든 인수
};
func1(1, 2, 3); // Arguments(3) [1, 2, 3]
// 화살표 함수: arguments 객체 사용 불가
const func2 = () => {
console.log(arguments); // 에러!
};
func2(1, 2, 3); // ReferenceError
// 대신 나머지 매개변수 사용
const func3 = (...args) => {
console.log(args); // [1, 2, 3]
};
func3(1, 2, 3); // [1, 2, 3]
실전 예제
예제 1: DOM 조작
// HTML
// <button id="btn">클릭</button>
// <div id="result"></div>
const button = document.getElementById('btn');
const result = document.getElementById('result');
// 익명 함수 사용
button.addEventListener('click', function() {
result.textContent = '버튼이 클릭되었습니다!';
this.style.backgroundColor = 'red'; // this가 button을 가리킴
});
// 화살표 함수 사용
button.addEventListener('click', () => {
result.textContent = '버튼이 클릭되었습니다!';
button.style.backgroundColor = 'blue'; // this 대신 button 직접 사용
});
예제 2: 배열 처리
const students = [
{ name: "홍길동", score: 85 },
{ name: "김철수", score: 92 },
{ name: "이영희", score: 78 }
];
// 익명 함수 사용
const highScores1 = students.filter(function(student) {
return student.score >= 80;
});
// 화살표 함수 사용 (더 간결)
const highScores2 = students.filter(student => student.score >= 80);
console.log(highScores1);
console.log(highScores2);
예제 3: 비동기 처리 (Promise)
// 익명 함수 사용
fetch('https://api.example.com/data')
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.error(error);
});
// 화살표 함수 사용 (더 간결)
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
예제 4: 클로저 (Closure)
// 익명 함수로 클로저 생성
const createCounter1 = function() {
let count = 0;
return function() {
return ++count;
};
};
const counter1 = createCounter1();
console.log(counter1()); // 1
console.log(counter1()); // 2
// 화살표 함수로 클로저 생성
const createCounter2 = () => {
let count = 0;
return () => ++count;
};
const counter2 = createCounter2();
console.log(counter2()); // 1
console.log(counter2()); // 2
예제 5: 고차 함수 (Higher-Order Function)
// 함수를 반환하는 함수
const multiply = (x) => {
return (y) => x * y;
};
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// 더 간단한 형태
const multiply2 = x => y => x * y;
const double2 = multiply2(2);
console.log(double2(5)); // 10
예제 6: 실제 프로젝트 예제 (아코디언 메뉴)
// 익명 함수 사용
document.addEventListener('DOMContentLoaded', function() {
const menuLinks = document.querySelectorAll('.menu-link');
menuLinks.forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
const subMenu = this.nextElementSibling;
// this가 link 요소를 가리킴
subMenu.classList.toggle('active');
});
});
});
// 화살표 함수 사용
document.addEventListener('DOMContentLoaded', () => {
const menuLinks = document.querySelectorAll('.menu-link');
menuLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const subMenu = link.nextElementSibling;
// this 대신 link 직접 사용
subMenu.classList.toggle('active');
});
});
});
주의사항
1. this 바인딩 주의
const obj = {
name: "홍길동",
items: [1, 2, 3],
// ❌ 잘못된 사용: 화살표 함수에서 this 사용
print1: () => {
this.items.forEach(item => {
console.log(this.name + ": " + item); // this.name이 undefined
});
},
// ✅ 올바른 사용: 익명 함수 사용
print2: function() {
this.items.forEach(item => {
console.log(this.name + ": " + item); // 정상 작동
});
},
// ✅ 올바른 사용: 화살표 함수지만 this를 사용하지 않음
print3: function() {
const name = this.name; // 미리 저장
this.items.forEach(item => {
console.log(name + ": " + item); // 정상 작동
});
}
};
2. 메서드 정의 시 주의
const obj = {
// ✅ 일반 메서드: this가 obj를 가리킴
method1: function() {
return this;
},
// ❌ 화살표 함수: this가 상위 스코프를 가리킴
method2: () => {
return this; // window 또는 global
},
// ✅ ES6 메서드 축약형 (권장)
method3() {
return this; // obj를 가리킴
}
};
3. 프로토타입 메서드 정의 시 주의
function Person(name) {
this.name = name;
}
// ✅ 익명 함수 사용 (권장)
Person.prototype.greet = function() {
return "안녕하세요, " + this.name;
};
// ❌ 화살표 함수 사용 (this가 Person 생성자가 아닌 상위 스코프를 가리킴)
Person.prototype.greet2 = () => {
return "안녕하세요, " + this.name; // undefined
};
4. 이벤트 리스너에서 this 사용 시 주의
const button = document.querySelector('button');
// ✅ 익명 함수: this가 button을 가리킴
button.addEventListener('click', function() {
console.log(this); // <button> 요소
this.style.color = 'red';
});
// ❌ 화살표 함수: this가 window를 가리킴
button.addEventListener('click', () => {
console.log(this); // window 객체
this.style.color = 'red'; // 에러 발생 가능
});
// ✅ 화살표 함수 사용 시: 이벤트 객체 사용
button.addEventListener('click', (e) => {
console.log(e.target); // <button> 요소
e.target.style.color = 'red';
});
언제 무엇을 사용할까?
익명 함수를 사용하는 경우
- 메서드 정의 (객체의 메서드)
- 생성자 함수
- this가 필요한 경우 (이벤트 리스너, 메서드)
- arguments 객체가 필요한 경우
화살표 함수를 사용하는 경우
- 콜백 함수 (map, filter, forEach 등)
- 간단한 함수 (한 줄로 표현 가능한 경우)
- this 바인딩이 필요 없는 경우
- 비동기 처리 (Promise, async/await)
요약
| 특징 | 익명 함수 | 화살표 함수 |
|---|---|---|
| 문법 | function() {} |
() => {} |
| this 바인딩 | 호출한 객체 | 상위 스코프 |
| 생성자 함수 | 가능 | 불가능 |
| arguments 객체 | 사용 가능 | 사용 불가 |
| 코드 길이 | 길다 | 짧다 |
| 호이스팅 | 안 됨 | 안 됨 |
연습 문제
문제 1: 배열 변환
다음 배열을 화살표 함수를 사용하여 각 요소를 제곱한 배열을 만드세요.
const numbers = [1, 2, 3, 4, 5];
// 답: [1, 4, 9, 16, 25]
문제 2: 필터링
다음 배열에서 짝수만 필터링하세요 (화살표 함수 사용).
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
// 답: [2, 4, 6, 8]
문제 3: 이벤트 리스너
버튼 클릭 시 "클릭되었습니다!"를 출력하는 이벤트 리스너를 작성하세요 (두 가지 방법 모두).
문제 4: 객체 메서드
다음 코드에서 올바르게 작동하도록 수정하세요.
const calculator = {
value: 0,
add: (num) => {
this.value += num; // 문제: this가 calculator를 가리키지 않음
}
};
정답
문제 1 정답
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(num => num * num);
console.log(squared); // [1, 4, 9, 16, 25]
문제 2 정답
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6, 8]
문제 3 정답
// 방법 1: 익명 함수
button.addEventListener('click', function() {
console.log('클릭되었습니다!');
});
// 방법 2: 화살표 함수
button.addEventListener('click', () => {
console.log('클릭되었습니다!');
});
문제 4 정답
// 방법 1: 익명 함수 사용
const calculator = {
value: 0,
add: function(num) {
this.value += num;
}
};
// 방법 2: ES6 메서드 축약형
const calculator = {
value: 0,
add(num) {
this.value += num;
}
};
이제 익명 함수와 화살표 함수를 완벽하게 이해하셨습니다! 🎉
'FrontEnd > Javascript' 카테고리의 다른 글
| 아코디언 메뉴 (Width 방식) (0) | 2026.02.13 |
|---|---|
| 아코디언 메뉴 (Height + CSS Transition 방식) (0) | 2026.02.13 |
| 모바일 메뉴(햄버거메뉴) - 네비 (0) | 2026.02.12 |
| JavaScript DOM과 이벤트 완전 정복 (1) | 2026.02.06 |
| 14장. 실습 문제 (0) | 2026.01.13 |