본문 바로가기

자바스크립트 관련

자바스크립트 함수 선언과 표현식

자바스크립트는 현대 웹 개발에서 중요한 역할을 하며, 특히 함수 선언과 표현식을 통해 강력한 기능을 제공합니다. 함수는 코드를 구조화하고 재사용성을 높이는 데 필수적인 요소입니다. 이를 활용하면 더 효율적이고 유지보수 가능한 코드를 작성할 수 있습니다.

함수 선언 (Function Declaration)

함수 선언은 function 키워드를 사용하여 함수를 정의하는 방법입니다. 함수 선언은 코드의 어느 위치에서든 호출할 수 있으며, 자바스크립트 엔진이 함수 선언을 호이스팅(hoisting)하기 때문에 코드의 처음부터 접근 가능합니다. 함수 선언은 프로그램 실행 시점에 미리 메모리에 로드되기 때문에 코드에서 호출되는 위치보다 앞에 정의될 필요는 없습니다.

function greet(name) {
return `Hello, ${name}!`;
}

이러한 함수 선언은 간단하면서도 읽기 쉬운 문법을 제공하여 많은 개발자들이 기본으로 사용하는 방식입니다. 함수 선언 방식은 이름이 고정되어 있어 코드를 읽을 때 함수의 목적을 명확하게 이해할 수 있도록 해줍니다. 또한 함수의 범위(scope)와 클로저(closure)에 대한 이해를 바탕으로 복잡한 로직을 단순화할 수 있습니다.

함수 표현식 (Function Expression)

함수 표현식은 다른 변수에 함수를 할당하여 함수처럼 사용하는 방식입니다. 이 방식에서는 함수를 변수에 대입하여 사용할 수 있으며, 변수에 할당된 함수는 함수 표현식이라 불립니다. 일반적으로 함수를 정의하고, 나중에 필요할 때 호출하는데 사용됩니다.

const greet = function(name) {
return `Hello, ${name}!`;
};

위와 같은 방식은 함수가 변수에 저장되어 호이스팅되지 않는다는 점에서 함수 선언과 차별화됩니다. 이는 주로 익명 함수 형태로 사용되며, 이들 함수는 선언이 이루어진 후에만 접근할 수 있습니다. 더욱이, 함수 표현식은 자바스크립트에서 콜백(callback)으로 함수를 전달해야 하는 경우에 많이 사용됩니다. 이는 코드 흐름의 유연성을 강화하며 비동기적인 작업을 수행하는 데 매우 유용합니다.

화살표 함수 (Arrow Function)

ES6에서 소개된 화살표 함수는 함수를 선언하는 더 짧고 간결한 방법을 제공합니다. 특히, 화살표 함수는 this의 바인딩을 유지한다는 점에서 기존 함수 표현식과 차이가 있습니다. 화살표 함수는 코드 양을 줄이고 가독성을 높이는 데 유용합니다.

const greet = (name) => {
return `Hello, ${name}!`;
};

위의 예제는 동일한 기능을 하는 함수를 화살표 함수 문법으로 정의한 것입니다. 단 한 줄의 명령일 경우 중괄호와 return 키워드를 생략할 수도 있어 더욱 간략하다는 장점이 있습니다. 이러한 형태는 주로 콜백 함수를 선언할 때 매우 유용하게 활용됩니다.

함수 호이스팅 (Function Hoisting)

함수 선언이 코드의 어떤 위치에서든 호출 가능한 이유는 자바스크립트의 호이스팅 개념 때문입니다. 자바스크립트 엔진은 코드 실행 전에 모든 함수와 변수를 메모리 상단으로 끌어올립니다. 따라서 함수 선언은 코드 내 어디에 위치하든 상관없이 호출될 수 있습니다. 하지만 함수 표현식은 호이스팅되지 않으므로, 해당하는 변수가 선언되기 전에는 사용할 수 없습니다.

호이스팅 특징을 잘 활용하면 코드의 구조를 유연하게 작성할 수 있으며, 복잡한 스크립트에서도 유연하게 함수를 사용할 수 있습니다. 그러나 코드 가독성 측면에서는 주의가 필요하며, 어디에서 함수가 정의되었는지를 명확하게 구분하는 것이 유지보수에 유리합니다. 특히 여러 개발자가 협력하는 프로젝트에서는 변수와 함수의 선언 위치를 명확히 하고, 호이스팅의 영향을 줄이는 것이 중요합니다.

함수 선언 측면 설명
호이스팅 함수 선언은 코드의 어느 위치에서든 호출 가능
명명 규칙 명확한 함수 명칭 제공
사용 사례 재사용 가능성이 높은 유틸리티 함수

익명 함수와 네임드 함수

익명 함수는 이름이 없는 함수로, 즉각적이거나 일회성으로 호출, 혹은 콜백으로 전달되는 용도로 사용됩니다. 반대로 네임드 함수는 함수의 이름을 명시하여 호출할 수 있습니다. 익명 함수는 주로 함수 표현식이나, 즉시 실행 함수 표현식(IIFE)로 사용되며, 함수명 대신 변수를 통해 호출됩니다.

익명 함수는 즉석에서 사용되거나 변수에 할당되며, 단발성 작업을 수행할 때 유용합니다. 반면 네임드 함수는 함수 코드를 명시적으로 이해하기 쉽고, 재사용성을 높인다는 점에서 장점이 있습니다. 네임드 함수는 주로 복잡한 로직을 포함할 때, 코드의 체계적인 이해를 높이는 데 쓰입니다.

즉시 실행 함수 표현식 (IIFE)

즉시 실행 함수 표현식(IIFE, Immediately Invoked Function Expression)은 함수를 정의하자마자 즉시 실행하는 고급 기법입니다. 이 기법은 주로 전역 변수 오염을 막고 코드의 독립성을 확보할 때 사용됩니다.

(function() {
console.log("This function executes immediately!");
})();

IIFE는 닫힌 환경(클로저)을 만들어 외부 코드로부터의 영향을 차단합니다. 이는 주로 라이브러리 작성 시 유용하게 사용되며, 클래식 자바스크립트 패턴 중 하나입니다. 또한 선언과 동시에 실행되므로 즉시 실행 함수의 내부 변수는 외부에서 접근할 수 없습니다. IIFE를 활용한 스코프 분리는 복잡한 스크립트 환경에서 변수를 지역적으로 제한하는데 큰 장점을 제공합니다.

클로저 (Closure)

클로저는 함수와 그 함수가 선언된 어휘적 환경의 조합입니다. 클로저는 자바스크립트의 강력한 기능 중 하나로, 함수가 생성될 때의 환경을 기억했다가 폐쇄된 범위에서도 참조할 수 있게 합니다. 이는 주로 데이터의 은닉성과 상태 유지가 필요한 경우에 사용됩니다.

function outerFunction() {
let outerVariable = 'I am outside!';

function innerFunction() {
console.log(outerVariable);
}

return innerFunction;
}

const closureFunction = outerFunction();
closureFunction();

위 예시에서 innerFunctionouterVariable에 접근할 수 있는데, 이는 클로저의 기본적인 동작 방식입니다. 이런 특성 덕분에 클로저는 비공개 데이터를 안전하게 유지하거나, 함수의 실행 컨텍스트를 지속할 수 있게 합니다.

고차 함수 (Higher-Order Function)

고차 함수는 다른 함수를 인자로 받거나, 결과로 함수를 반환하는 함수입니다. 이러한 함수는 함수형 프로그래밍의 주요 개념 중 하나로, 코드의 재사용성과 유연성을 높이는 데 도움이 됩니다. 자바스크립트의 배열 메서드인 .map(), .filter(), .reduce() 등이 대표적인 고차 함수입니다.

function higherOrderFunction(fn, message) {
return fn(message);
}

const sayHello = (name) => `Hello, ${name}!`;
console.log(higherOrderFunction(sayHello, 'JavaScript'));

고차 함수는 결합과 합성(compose), 커링(currying) 등의 패턴을 구현할 때 널리 사용됩니다. 이러한 함수는 코드에서 중복을 피하고 다양한 기능을 유연하게 조합할 수 있는 강력한 도구 역할을 합니다. 이는 코드의 추상화를 돕고, 코드를 모듈화하여 여러 컴포넌트로 나눌 수 있게 합니다.

함수표현식의 다양한 활용 예시

  1. 익명 함수 - 익명 함수는 주어진 컨텍스트 내에서 즉시 실행되거나 콜백으로 사용됩니다. 코드의 응집성을 높이고 소규모 단위로 처리할 때 주로 사용되며, 주로 고차 함수와 함께 쓰입니다.

  2. 네임드 함수 표현식 - 네임드 함수 표현식은 함수의 이름을 포함하여 선언하는 방법입니다. 이는 스택 추적(stack trace), 재귀(recursion)의 용도로, 함수 자신이 자신을 호출해야 할 필요가 있을 때 사용됩니다.

  3. 성능 최적화 - 함수 표현식은 고차 함수와 결합하여 다양한 성능 최적화 기법에 사용됩니다. 이를 통해 실행 시간과 메모리 사용을 효율적으로 관리할 수 있습니다.

  4. 모듈화 - 자바스크립트의 모듈화 패턴에서 함수 표현식을 사용하면, 각 함수의 독립성을 보장받으며 자체적으로 관리할 수 있습니다.

  5. 콜백 함수 - 비순차적 코드 실행 시, 즉각적인 전달과 처리를 위해 자주 쓰이며, 주로 이벤트 핸들러나 비동기 처리로 활용됩니다.

자바스크립트 함수의 비동기 처리

자바스크립트는 비동기 처리를 위한 다양한 방법을 제공합니다. 이러한 방법은 주로 callback, Promise, async/await 등을 통해 구현됩니다. 비동기 처리는 네트워크 요청, 파일 입출력 등 시간이 걸리는 작업을 효율적으로 처리하는 데 초점을 맞춥니다.

비동기적 함수 호출과 콜백

비동기적 함수 호출은 함수가 완료될 때까지 애플리케이션의 흐름을 차단하지 않고, 이후 필요한 작업을 지정된 콜백 함수 내에서 수행하도록 합니다. 이는 특히 비블로킹 I/O나 API 호출에서 유용하게 사용됩니다.

function fetchData(callback) {
setTimeout(() => {
callback("Data fetched successfully");
}, 1000);
}

fetchData((message) => {
console.log(message);
});

콜백을 통해 비동기 요청의 결과가 준비될 때까지 기다릴 필요 없이 다른 일을 수행하고, 준비가 되면 지정된 콜백 함수가 호출되어 결과를 처리할 수 있습니다. 이는 프로그램의 응답성을 높이고 사용자 경험을 개선하는 방법 중 하나입니다.

함수 선언 vs 표현식: 차이점과 선택 기준

자바스크립트에서는 함수 선언과 표현식 모두 함수를 생성하는 게 가능하지만, 이 두 가지 방법에는 약간의 차이가 있습니다. 함수 선언은 호이스팅되어 프로그램 어디서든 호출할 수 있습니다. 반면, 함수 표현식은 변수에 저장되기 때문에 선언 후에만 호출 가능합니다.

어떤 방법을 선택할지는 주로 코드의 구조적 요구사항, 가독성과 유지보수성에 달려 있습니다. 예를 들어, 라이브러리나 프레임워크 같은 대규모 코드베이스의 경우, 명시적이고 체계적인 접근을 위해 함수 선언을 사용하는 것이 더 나을 수 있습니다. 반면, 콜백이나 비동기 작업처럼 일시적이고 문맥에 따라 유연성이 필요한 경우, 함수 표현식을 사용하는 것이 일반적입니다.

함수 사용의 최적화 및 성능 향상

함수 사용의 최적화는 여러 측면에서 이루어질 수 있습니다. 코드의 재사용성과 유지보수성은 물론, 런타임 성능까지 고려해야 합니다. 이를 위해서는 불필요한 중복을 제거하고, 익명 함수와 클로저를 적절히 활용해야 합니다.

또한, 함수의 스코프를 잘 관리하여 메모리 누수를 방지하고, 불필요한 재계산을 최소화하는 방향으로 설계할 필요가 있습니다. 이것은 특히 데이터 중심의 애플리케이션 또는 복잡한 연산이 필요한 경우 중요합니다. 효율적인 코드를 작성함으로써 앱의 성능과 사용자 만족도를 동시에 높일 수 있습니다.