JavaScript Functions
JavaScript Functions: 심층 분석과 활용 전략
JavaScript는 웹 개발에서 핵심적인 역할을 하는 프로그래밍 언어로, **함수(Functions)**는 코드의 재사용성과 구조화를 높이는 데 필수적인 도구입니다. 함수를 정확히 이해하고 활용하는 것은 효율적이고 유지보수가 용이한 코드를 작성하는 데 매우 중요합니다. 이 가이드에서는 JavaScript에서 사용되는 다양한 함수의 개념과 그 활용 방법에 대해 심층적으로 분석하고 전략적으로 접근하는 방법을 알아보겠습니다.
1. 함수란?
- *함수(Function)**는 특정 작업을 수행하는 코드 블록으로, 필요할 때마다 호출하여 사용할 수 있습니다. 함수는 코드의 재사용성을 높이고, 복잡한 로직을 단순화하며, 프로그램의 구조를 체계적으로 관리하는 데 도움을 줍니다.
1.1. 함수의 중요성
- 재사용성: 동일한 코드를 여러 번 작성하지 않고도 필요할 때마다 호출하여 사용할 수 있습니다.
- 가독성 향상: 복잡한 로직을 함수로 분리하여 코드의 가독성을 높입니다.
- 유지보수 용이: 함수 단위로 코드를 관리하면 수정과 디버깅이 용이해집니다.
- 모듈화: 프로그램을 작은 단위로 나누어 모듈화함으로써 관리와 확장이 용이해집니다.
2. 함수 선언 방식
JavaScript에서는 여러 가지 방식으로 함수를 선언할 수 있습니다. 주요 함수 선언 방식은 다음과 같습니다:
- 함수 선언문(Function Declaration)
- 함수 표현식(Function Expression)
- 화살표 함수(Arrow Function)
2.1. 함수 선언문(Function Declaration)
함수 선언문은 function
키워드를 사용하여 함수를 선언하는 방식입니다. 함수 선언문은 호이스팅(hoisting)의 영향을 받아 함수가 선언되기 전에 호출할 수 있습니다.
예제
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // 출력: Hello, Alice!
특징
- 호이스팅: 함수 선언문은 코드의 최상단으로 호이스팅되어, 선언 전에 호출해도 정상적으로 작동합니다.
- 명명된 함수: 함수에 이름을 부여하여 디버깅 시 유용합니다.
2.2. 함수 표현식(Function Expression)
함수 표현식은 함수를 변수에 할당하는 방식입니다. 익명 함수나 명명된 함수를 사용할 수 있습니다.
예제
// 익명 함수 표현식
const greet = function(name) {
return `Hello, ${name}!`;
};
console.log(greet("Bob")); // 출력: Hello, Bob!
// 명명된 함수 표현식
const greetNamed = function greetUser(name) {
return `Hello, ${name}!`;
};
console.log(greetNamed("Charlie")); // 출력: Hello, Charlie!
특징
- 호이스팅 없음: 함수 표현식은 변수의 호이스팅에 영향을 받으며, 함수 선언 전에 호출하면
TypeError
가 발생합니다. - 유연성: 함수를 변수에 할당하거나, 다른 함수의 인자로 전달할 수 있습니다.
2.3. 화살표 함수(Arrow Function)
화살표 함수는 ES6에서 도입된 간결한 함수 선언 방식입니다. =>
문법을 사용하며, this
바인딩 방식이 기존 함수와 다릅니다.
예제
// 기본 화살표 함수
const greet = (name) => {
return `Hello, ${name}!`;
};
console.log(greet("Dave")); // 출력: Hello, Dave!
// 단일 표현식 화살표 함수 (암시적 반환)
const greetImplicit = name => `Hello, ${name}!`;
console.log(greetImplicit("Eve")); // 출력: Hello, Eve!
특징
- 간결한 문법: 코드가 짧고 읽기 쉽습니다.
this
바인딩: 화살표 함수는 자신만의this
를 가지지 않고, 외부 컨텍스트의this
를 사용합니다.- 함수 생성 불가: 생성자 함수로 사용할 수 없으며,
new
키워드와 함께 사용할 수 없습니다.
3. 함수 매개변수와 인자
함수는 매개변수(parameters)와 인자(arguments)를 통해 데이터를 전달받을 수 있습니다.
3.1. 매개변수와 인자
- 매개변수(Parameter): 함수 정의 시 선언되는 변수입니다.
- 인자(Argument): 함수 호출 시 전달되는 실제 값입니다.
예제
function add(a, b) {
return a + b;
}
console.log(add(5, 3)); // 출력: 8
3.2. 기본 매개변수(Default Parameters)
함수 호출 시 인자가 제공되지 않으면 기본값을 설정할 수 있습니다.
예제
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // 출력: Hello, Guest!
console.log(greet("Frank")); // 출력: Hello, Frank!
3.3. 나머지 매개변수(Rest Parameters)
함수에 전달되는 인자의 개수가 정해지지 않았을 때, 나머지 인자를 배열로 받을 수 있습니다.
예제
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 출력: 10
3.4. 전개 연산자(Spread Operator)
배열이나 객체의 요소를 개별 인자로 전달할 때 사용됩니다.
예제
const numbers = [1, 2, 3];
function multiply(a, b, c) {
return a * b * c;
}
console.log(multiply(...numbers)); // 출력: 6
4. 함수 반환값(Return Values)
함수는 값을 반환할 수 있으며, return
키워드를 사용합니다. 반환값이 없는 함수는 undefined
를 반환합니다.
예제
function multiply(a, b) {
return a * b;
}
const result = multiply(4, 5);
console.log(result); // 출력: 20
5. 스코프와 호이스팅
함수의 스코프(Scope)는 변수가 접근할 수 있는 범위를 결정합니다. JavaScript는 함수 스코프와 블록 스코프를 지원하며, 호이스팅(hoisting) 개념이 존재합니다.
5.1. 스코프(Scope)
- 전역 스코프(Global Scope): 전체 코드에서 접근 가능한 변수.
- 지역 스코프(Local Scope): 함수 내에서만 접근 가능한 변수.
- 블록 스코프(Block Scope): 블록(
{}
) 내에서만 접근 가능한 변수 (let
,const
).
예제
let globalVar = "I am global";
function example() {
let localVar = "I am local";
console.log(globalVar); // 접근 가능
console.log(localVar); // 접근 가능
}
example();
console.log(globalVar); // 접근 가능
console.log(localVar); // ReferenceError: localVar is not defined
5.2. 호이스팅(Hoisting)
JavaScript는 변수와 함수 선언을 코드의 최상단으로 끌어올리는 호이스팅을 수행합니다. 함수 선언문은 호이스팅되어 선언 전에 호출할 수 있지만, 함수 표현식은 변수 호이스팅의 영향을 받습니다.
함수 선언문의 호이스팅 예제
console.log(greet("Grace")); // 출력: Hello, Grace!
function greet(name) {
return `Hello, ${name}!`;
}
함수 표현식의 호이스팅 예제
console.log(greet("Hank")); // TypeError: greet is not a function
const greet = function(name) {
return `Hello, ${name}!`;
};
6. 클로저(Closures)
- *클로저(Closure)**는 함수가 자신이 선언된 렉시컬 환경(Lexical Environment)을 기억하는 특성을 말합니다. 클로저를 사용하면 외부 함수의 변수에 접근할 수 있으며, 데이터 은닉과 캡슐화에 유용합니다.
예제
function makeCounter() {
let count = 0;
return function() {
count += 1;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 출력: 1
console.log(counter()); // 출력: 2
console.log(counter()); // 출력: 3
클로저의 활용
- 데이터 은닉: 내부 변수를 외부에서 직접 접근하지 못하게 보호할 수 있습니다.
- 캡슐화: 관련된 데이터를 함수 내부에 묶어 관리할 수 있습니다.
- 모듈 패턴: 클로저를 사용하여 모듈을 구현하고, 공용 API를 노출할 수 있습니다.
7. 고차 함수(Higher-Order Functions)
- *고차 함수(Higher-Order Functions)**는 함수를 인자로 받거나 함수를 반환하는 함수입니다. 고차 함수를 사용하면 함수형 프로그래밍의 개념을 도입할 수 있으며, 코드의 추상화와 재사용성을 높일 수 있습니다.
예제
// 함수를 인자로 받는 고차 함수
function applyOperation(a, b, operation) {
return operation(a, b);
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
console.log(applyOperation(5, 3, add)); // 출력: 8
console.log(applyOperation(5, 3, multiply)); // 출력: 15
배열 메서드와 고차 함수
JavaScript의 배열 메서드인 map
, filter
, reduce
등은 고차 함수의 대표적인 예입니다.
예제
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 even = numbers.filter(num => num % 2 === 0);
console.log(even); // 출력: [2, 4]
// reduce: 배열의 모든 요소를 누적하여 단일 값으로 축소
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 출력: 15
8. 콜백 함수(Callback Functions)
- *콜백 함수(Callback Functions)**는 다른 함수의 인자로 전달되어 특정 작업이 완료된 후 호출되는 함수입니다. 비동기 작업이나 이벤트 핸들링에서 자주 사용됩니다.
예제
function fetchData(callback) {
setTimeout(() => {
const data = { name: "Ivy", age: 28 };
callback(data);
}, 1000);
}
function displayData(data) {
console.log(`Name: ${data.name}, Age: ${data.age}`);
}
fetchData(displayData); // 1초 후 출력: Name: Ivy, Age: 28
콜백 지옥(Callback Hell)
여러 개의 콜백 함수가 중첩되면서 코드의 가독성이 떨어지고 유지보수가 어려워지는 문제를 말합니다. 이를 해결하기 위해 프라미스(Promise)나 async/await
문법을 사용할 수
있습니다.
9. 즉시 실행 함수 표현식(IIFE)
- *즉시 실행 함수 표현식(IIFE, Immediately Invoked Function Expression)**은 선언과 동시에 즉시 실행되는 함수입니다. 주로 변수의 스코프를 제한하거나 초기화 작업을 수행할 때 사용됩니다.
예제
(function() {
const message = "This is an IIFE";
console.log(message); // 출력: This is an IIFE
})();
// 외부에서 message에 접근 불가
// console.log(message); // ReferenceError: message is not defined
특징
- 스코프 격리: 변수의 충돌을 방지하고, 전역 네임스페이스를 오염시키지 않습니다.
- 초기화 작업: 초기 설정이나 데이터 로딩 시점에 필요한 작업을 수행합니다.
10. 재귀 함수(Recursion)
- *재귀 함수(Recursion)**는 함수가 자기 자신을 호출하는 방식입니다. 주로 반복적인 작업이나 트리 구조 탐색 등에 사용됩니다.
예제
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 출력: 120
주의사항
- 종료 조건: 재귀 함수는 반드시 종료 조건을 가져야 하며, 그렇지 않으면 무한 재귀로 인해 스택 오버플로우가 발생할 수 있습니다.
- 성능: 깊은 재귀는 메모리 사용량을 증가시키고 성능에 영향을 줄 수 있습니다. 필요 시 반복문으로 대체하는 것을 고려해야 합니다.
11. 커링(Currying)
- *커링(Currying)**은 여러 개의 인자를 받는 함수를 단일 인자를 받는 일련의 함수로 변환하는 기법입니다. 함수의 유연성을 높이고, 부분 적용(partial application)을 가능하게 합니다.
예제
function multiply(a) {
return function(b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5)); // 출력: 10
const triple = multiply(3);
console.log(triple(5)); // 출력: 15
특징
- 함수 조합: 다양한 방식으로 함수를 조합하여 사용할 수 있습니다.
- 유연성: 함수의 일부 인자를 미리 적용하여 새로운 함수를 생성할 수 있습니다.
12. 함수 바인딩(Function Binding)
JavaScript의 함수는 this
키워드를 가질 수 있으며, 이를 명확히 하기 위해 bind
, call
,
apply
메서드를 사용할 수 있습니다.
12.1. bind
메서드
bind
는 함수의 this
값을 고정시킨 새로운 함수를 반환합니다.
예제
const person = {
name: "Jack",
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
const greet = person.greet.bind(person);
greet(); // 출력: Hello, Jack!
12.2. call
메서드
call
은 함수의 this
값을 지정하고, 개별 인자를 전달하여 함수를 즉시 호출합니다.
예제
function greet(greeting) {
console.log(`${greeting}, ${this.name}!`);
}
const person = { name: "Karen" };
greet.call(person, "Hi"); // 출력: Hi, Karen!
12.3. apply
메서드
apply
는 call
과 유사하지만, 인자를 배열 형태로 전달합니다.
예제
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const person = { name: "Leo" };
greet.apply(person, ["Hello", "!"]); // 출력: Hello, Leo!
13. 함수형 프로그래밍(Function Programming) 개념
JavaScript는 함수형 프로그래밍 패러다임을 지원하여, 함수를 일급 객체로 취급하고, 순수 함수, 불변성, 고차 함수 등의 개념을 활용할 수 있습니다.
13.1. 순수 함수(Pure Functions)
순수 함수는 동일한 입력에 대해 항상 동일한 출력을 반환하며, 외부 상태를 변경하지 않는 함수입니다.
예제
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 출력: 5
console.log(add(2, 3)); // 출력: 5
13.2. 불변성(Immutability)
데이터를 변경하지 않고, 새로운 데이터를 생성하여 사용하는 개념입니다. 이는 버그를 줄이고, 예측 가능한 코드를 작성하는 데 도움이 됩니다.
예제
const original = [1, 2, 3];
const newArray = [...original, 4];
console.log(original); // 출력: [1, 2, 3]
console.log(newArray); // 출력: [1, 2, 3, 4]
13.3. 고차 함수(Higher-Order Functions)
앞서 설명한 고차 함수 개념을 다시 언급하며, 함수형 프로그래밍에서 중요한 역할을 합니다.
14. 모듈(Module)과 함수
JavaScript의 모듈 시스템을 활용하여 함수를 외부 파일로 분리하고, 필요할 때마다 불러와 사용할 수 있습니다. 이는 코드의 재사용성과 유지보수를 향상시키는 데 도움이 됩니다.
예제
모듈 정의 (math.js)
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
모듈 사용 (main.js)
import { add, multiply } from './math.js';
console.log(add(5, 3)); // 출력: 8
console.log(multiply(5, 3)); // 출력: 15
특징
- 캡슐화: 관련된 함수와 변수를 하나의 모듈로 묶어 관리할 수 있습니다.
- 재사용성: 모듈을 여러 파일에서 재사용할 수 있습니다.
- 명확한 의존성: 필요한 모듈만을 명시적으로 불러와 사용합니다.
15. 비동기 함수(Asynchronous Functions)
JavaScript는 비동기 작업을 처리하기 위해 다양한 방법을 제공합니다. 대표적인 비동기 함수는 콜백, 프로미스(Promise), async/await
입니다.
15.1. 프로미스(Promise)
프로미스는 비동기 작업의 완료 또는 실패를 나타내는 객체입니다.
예제
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "Mia", age: 30 };
resolve(data);
}, 1000);
});
fetchData
.then(data => console.log(data)) // 1초 후 출력: { name: "Mia", age: 30 }
.catch(error => console.error(error));
15.2. async/await
async/await
는 프로미스를 기반으로 한 비동기 코드를 동기 코드처럼 작성할 수 있게 해줍니다.
예제
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "Nina", age: 25 };
resolve(data);
}, 1000);
});
}
async function displayData() {
try {
const data = await fetchData();
console.log(data); // 출력: { name: "Nina", age: 25 }
} catch (error) {
console.error(error);
}
}
displayData();
특징
- 가독성 향상: 비동기 코드를 동기 코드처럼 작성할 수 있어 가독성이 높습니다.
- 에러 처리 용이:
try...catch
문을 사용하여 에러를 쉽게 처리할 수 있습니다.
16. 요약
- 함수의 개념: 함수는 특정 작업을 수행하는 코드 블록으로, 재사용성과 코드 구조화를 높이는 데 필수적입니다.
- 함수 선언 방식: 함수 선언문, 함수 표현식, 화살표 함수 등 다양한 방식으로 함수를 선언할 수 있습니다.
- 매개변수와 인자: 함수는 매개변수를 통해 데이터를 받고, 인자를 통해 실제 값을 전달받습니다. 기본 매개변수, 나머지 매개변수, 전개 연산자 등을 활용할 수 있습니다.
- 함수 반환값: 함수는 값을 반환할 수 있으며,
return
키워드를 사용하여 반환합니다. - 스코프와 호이스팅: 함수의 스코프와 호이스팅 개념을 이해하여 변수 접근과 함수 호출 시의 동작 방식을 파악할 수 있습니다.
- 클로저: 클로저를 통해 함수가 자신이 선언된 렉시컬 환경을 기억하게 하여 데이터 은닉과 캡슐화를 구현할 수 있습니다.
- 고차 함수: 함수를 인자로 받거나 함수를 반환하는 고차 함수를 활용하여 코드의 추상화와 재사용성을 높일 수 있습니다.
- 콜백 함수: 다른 함수의 인자로 전달되어 특정 작업 후 호출되는 콜백 함수를 사용하여 비동기 작업을 처리할 수 있습니다.
- 즉시 실행 함수 표현식(IIFE): 선언과 동시에 실행되는 함수를 사용하여 스코프를 격리하고 초기화 작업을 수행할 수 있습니다.
- 재귀 함수: 함수가 자기 자신을 호출하여 반복적인 작업을 수행할 수 있으며, 종료 조건을 명확히 설정해야 합니다.
- 커링: 여러 개의 인자를 받는 함수를 단일 인자를 받는 일련의 함수로 변환하여 함수의 유연성을 높일 수 있습니다.
- 함수 바인딩:
bind
,call
,apply
메서드를 사용하여 함수의this
값을 명확히 설정할 수 있습니다. - 함수형 프로그래밍: 순수 함수, 불변성, 고차 함수 등의 개념을 활용하여 함수형 프로그래밍 패러다임을 적용할 수 있습니다.
- 모듈과 함수: 모듈 시스템을 활용하여 함수를 외부 파일로 분리하고, 필요한 곳에서 불러와 사용할 수 있습니다.
- 비동기 함수: 프로미스와
async/await
를 사용하여 비동기 작업을 효율적으로 처리할 수 있습니다.
함수를 정확하게 이해하고 다양한 기능을 활용하면 JavaScript 코드의 효율성과 유지보수성을 크게 향상시킬 수 있습니다. 이 가이드에서 소개한 개념과 예제를 통해 함수의 동작 방식을 직접 확인하고, 실제 프로젝트에 적용해보세요!
JavaScript Functions: 심층 분석과 활용 전략
JavaScript의 **함수(Function)**는 코드의 재사용성과 구조화를 높이는 데 필수적인 도구입니다. 이 가이드는 함수의 다양한 종류와 활용 방법을 심층적으로 분석하여, 실제 개발 상황에서 효과적으로 사용할 수 있는 전략을 제공합니다.
1. 함수의 종류 및 사용법
1.1. 함수 선언문(Function Declaration)
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // 출력: Hello, Alice!
1.2. 함수 표현식(Function Expression)
const greet = function(name) {
return `Hello, ${name}!`;
};
console.log(greet("Bob")); // 출력: Hello, Bob!
1.3. 화살표 함수(Arrow Function)
const greet = (name) => `Hello, ${name}!`;
console.log(greet("Charlie")); // 출력: Hello, Charlie!
2. 함수 매개변수와 인자
2.1. 기본 매개변수(Default Parameters)
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // 출력: Hello, Guest!
console.log(greet("Dave")); // 출력: Hello, Dave!
2.2. 나머지 매개변수(Rest Parameters)
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 출력: 10
2.3. 전개 연산자(Spread Operator)
const numbers = [1, 2, 3];
function multiply(a, b, c) {
return a * b * c;
}
console.log(multiply(...numbers)); // 출력: 6
3. 함수 반환값(Return Values)
function multiply(a, b) {
return a * b;
}
const result = multiply(4, 5);
console.log(result); // 출력: 20
4. 스코프와 호이스팅
4.1. 스코프(Scope)
let globalVar = "I am global";
function example() {
let localVar = "I am local";
console.log(globalVar); // 접근 가능
console.log(localVar); // 접근 가능
}
example();
console.log(globalVar); // 접근 가능
console.log(localVar); // ReferenceError: localVar is not defined
4.2. 호이스팅(Hoisting)
console.log(greet("Grace")); // 출력: Hello, Grace!
function greet(name) {
return `Hello, ${name}!`;
}
5. 클로저(Closures)
function makeCounter() {
let count = 0;
return function() {
count += 1;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 출력: 1
console.log(counter()); // 출력: 2
console.log(counter()); // 출력: 3
6. 고차 함수(Higher-Order Functions)
function applyOperation(a, b, operation) {
return operation(a, b);
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
console.log(applyOperation(5, 3, add)); // 출력: 8
console.log(applyOperation(5, 3, multiply)); // 출력: 15
7. 콜백 함수(Callback Functions)
function fetchData(callback) {
setTimeout(() => {
const data = { name: "Ivy", age: 28 };
callback(data);
}, 1000);
}
function displayData(data) {
console.log(`Name: ${data.name}, Age: ${data.age}`);
}
fetchData(displayData); // 1초 후 출력: Name: Ivy, Age: 28
8. 즉시 실행 함수 표현식(IIFE)
(function() {
const message = "This is an IIFE";
console.log(message); // 출력: This is an IIFE
})();
9. 재귀 함수(Recursion)
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 출력: 120
10. 커링(Currying)
function multiply(a) {
return function(b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5)); // 출력: 10
const triple = multiply(3);
console.log(triple(5)); // 출력: 15
11. 함수 바인딩(Function Binding)
11.1. bind
메서드
const person = {
name: "Jack",
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
const greet = person.greet.bind(person);
greet(); // 출력: Hello, Jack!
11.2. call
메서드
function greet(greeting) {
console.log(`${greeting}, ${this.name}!`);
}
const person = { name: "Karen" };
greet.call(person, "Hi"); // 출력: Hi, Karen!
11.3. apply
메서드
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const person = { name: "Leo" };
greet.apply(person, ["Hello", "!"]); // 출력: Hello, Leo!
12. 함수형 프로그래밍(Function Programming) 개념
12.1. 순수 함수(Pure Functions)
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 출력: 5
console.log(add(2, 3)); // 출력: 5
12.2. 불변성(Immutability)
const original = [1, 2, 3];
const newArray = [...original, 4];
console.log(original); // 출력: [1, 2, 3]
console.log(newArray); // 출력: [1, 2, 3, 4]
13. 모듈(Module)과 함수
예제
모듈 정의 (math.js)
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
모듈 사용 (main.js)
import { add, multiply } from './math.js';
console.log(add(5, 3)); // 출력: 8
console.log(multiply(5, 3)); // 출력: 15
14. 비동기 함수(Asynchronous Functions)
14.1. 프로미스(Promise)
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "Mia", age: 30 };
resolve(data);
}, 1000);
});
fetchData
.then(data => console.log(data)) // 1초 후 출력: { name: "Mia", age: 30 }
.catch(error => console.error(error));
14.2. async/await
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: "Nina", age: 25 };
resolve(data);
}, 1000);
});
}
async function displayData() {
try {
const data = await fetchData();
console.log(data); // 출력: { name: "Nina", age: 25 }
} catch (error) {
console.error(error);
}
}
displayData();
15. 요약
- 함수의 개념: 함수는 특정 작업을 수행하는 코드 블록으로, 재사용성과 코드 구조화를 높이는 데 필수적입니다.
- 함수 선언 방식: 함수 선언문, 함수 표현식, 화살표 함수 등 다양한 방식으로 함수를 선언할 수 있습니다.
- 매개변수와 인자: 함수는 매개변수를 통해 데이터를 받고, 인자를 통해 실제 값을 전달받습니다. 기본 매개변수, 나머지 매개변수, 전개 연산자 등을 활용할 수 있습니다.
- 함수 반환값: 함수는 값을 반환할 수 있으며,
return
키워드를 사용하여 반환합니다. - 스코프와 호이스팅: 함수의 스코프와 호이스팅 개념을 이해하여 변수 접근과 함수 호출 시의 동작 방식을 파악할 수 있습니다.
- 클로저: 클로저를 통해 함수가 자신이 선언된 렉시컬 환경을 기억하게 하여 데이터 은닉과 캡슐화를 구현할 수 있습니다.
- 고차 함수: 함수를 인자로 받거나 함수를 반환하는 고차 함수를 활용하여 코드의 추상화와 재사용성을 높일 수 있습니다.
- 콜백 함수: 다른 함수의 인자로 전달되어 특정 작업 후 호출되는 콜백 함수를 사용하여 비동기 작업을 처리할 수 있습니다.
- 즉시 실행 함수 표현식(IIFE): 선언과 동시에 실행되는 함수를 사용하여 스코프를 격리하고 초기화 작업을 수행할 수 있습니다.
- 재귀 함수: 함수가 자기 자신을 호출하여 반복적인 작업을 수행할 수 있으며, 종료 조건을 명확히 설정해야 합니다.
- 커링: 여러 개의 인자를 받는 함수를 단일 인자를 받는 일련의 함수로 변환하여 함수의 유연성을 높일 수 있습니다.
- 함수 바인딩:
bind
,call
,apply
메서드를 사용하여 함수의this
값을 명확히 설정할 수 있습니다. - 함수형 프로그래밍: 순수 함수, 불변성, 고차 함수 등의 개념을 활용하여 함수형 프로그래밍 패러다임을 적용할 수 있습니다.
- 모듈과 함수: 모듈 시스템을 활용하여 함수를 외부 파일로 분리하고, 필요한 곳에서 불러와 사용할 수 있습니다.
- 비동기 함수: 프로미스와
async/await
를 사용하여 비동기 작업을 효율적으로 처리할 수 있습니다.
함수를 정확하게 이해하고 다양한 기능을 활용하면 JavaScript 코드의 효율성과 유지보수성을 크게 향상시킬 수 있습니다. 이 가이드에서 소개한 개념과 예제를 통해 함수의 동작 방식을 직접 확인하고, 실제 프로젝트에 적용해보세요!