함수 선언(function)과 함수 표현식(const를 사용한 방법)의 차이
- 호이스팅
함수 선언: 함수 선언은 호이스팅됩니다. 즉, 함수 선언문은 코드의 어느 부분에서든 호출할 수 있습니다.console.log(greet("Alice")); // "Hello, Alice!" function greet(name) { return \`Hello, ${name}!\`; }
이 코드는 정상적으로 작동합니다. 왜냐하면 함수 선언이 호이스팅되기 때문에, greet 함수를 선언하기 전에 호출할 수 있습니다.
함수 표현식:
함수 표현식은 할당 전에 호출할 수 없습니다.
console.log(greet("Alice")); // ReferenceError: Cannot access 'greet' before initialization const greet = function(name) {
return `Hello, ${name}!`;
};
이 코드는 ReferenceError를 발생시킵니다. 왜냐하면 greet 변수는 선언되었지만 초기화되지 않았기 때문입니다.
- 익명 함수와 네임드 함수
익명 함수: 함수 표현식은 종종 익명 함수로 사용됩니다. 이는 코드가 더 간결해질 수 있습니다.
네임드 함수: 네임드 함수 표현식을 사용하면 디버깅 시 유용할 수 있습니다.
const greet = function greetFunction(name) {
return `Hello, ${name}!`;
};
- 일급 객체(first-class citizens)
JavaScript의 함수는 일급 객체이기 때문에, 함수 표현식은 함수 자체를 변수에 할당하거나 인자로 전달할 때 유용합니다.
콜백 함수: 함수 표현식을 사용하여 다른 함수의 인자로 전달할 수 있습니다.
고차 함수: 함수가 다른 함수를 반환할 수 있습니다.
const createGreeting = function(greeting) {
return function(name) {
return \`${greeting}, ${name}!\`;
};
};
const sayHello = createGreeting("Hello");
console.log(sayHello("Alice")); // "Hello, Alice!"
-
블록 스코프
const로 선언된 변수는 블록 스코프를 가지므로, 함수 표현식은 블록 스코프 내에서만 접근 가능하게 할 수 있습니다. -
코드 가독성 및 유지보수성
코드의 목적이나 팀의 스타일 가이드에 따라 함수 표현식을 사용하면 가독성이 향상될 수 있습니다. 특히 클로저나 콜백 함수와 함께 사용할 때 유용합니다.
결론
함수 선언은 함수가 호이스팅되어 어디서든 호출할 수 있게 하고, 코드의 구조가 명확해질 때 유용합니다.
함수 표현식은 블록 스코프를 활용하고, 함수 자체를 변수에 할당하거나 다른 함수의 인자로 전달할 때 유용합니다.
화살표 함수(Arrow Function)
ES6(ECMAScript 2015)에서 도입된 JavaScript의 함수 표현 방식 중 하나입니다. 일반적인 함수 선언 방식과는 달리, 보다 간결한 문법을 제공합니다.
화살표 함수의 기본 문법
const 함수이름 = (매개변수) => {
// 함수 본문
return 결과;
};
=>
: 화살표 함수의 핵심 부분으로, 매개변수 목록과 함수 본문을 구분합니다.
(ex)
const checkUsername = (username: string) => !username.includes("potato");
화살표 함수의 장점
간결한 문법: 화살표 함수는 일반적인 함수 선언보다 문법이 간결합니다.
암묵적 반환: 중괄호 없이 작성된 화살표 함수는 표현식의 결과를 암묵적으로 반환합니다. 위의 예시에서 중괄호와 return 키워드 없이도 !username.includes(“potato”)의 결과가 반환됩니다.
this 바인딩: 화살표 함수는 자신만의 this 값을 가지지 않습니다. 대신, 외부 컨텍스트의 this 값을 유지합니다. 이는 객체 메서드나 콜백 함수에서 유용할 수 있습니다.
- 매개변수가 하나일 때 괄호 생략 가능
- 매개변수가 없을 때 빈 괄호 사용
화살표 함수의 제한 사항
this 바인딩: 화살표 함수는 자신만의 this를 가지지 않기 때문에, 객체의 메서드로 사용할 때는 주의해야 합니다.
arguments 객체: 화살표 함수는 arguments 객체를 지원하지 않습니다. 대신, Rest 파라미터 문법을 사용할 수 있습니다.
new 키워드: 화살표 함수는 생성자 함수로 사용할 수 없습니다. new 키워드를 사용할 수 없습니다.
this
전역 문맥에서의 this: 전역 객체를 가리킵니다.
객체 메서드에서의 this: 해당 메서드를 소유한 객체를 가리킵니다.
일반 함수에서의 this: 전역 객체를 가리킵니다. (엄격 모드에서는 undefined)
생성자 함수에서의 this: 새로 생성된 인스턴스를 가리킵니다.
화살표 함수에서의 this: 자신만의 this를 가지지 않고, 외부 스코프의 this를 사용합니다.
superRefine의 ctx
.superRefine 메소드 내에서 사용되는 ctx는 Zod의 RefinementCtx 객체를 나타냅니다. 이는 사용자 정의 유효성 검사를 할 때 유효성 검사 과정에서 이슈를 추가하거나 조작할 수 있는 컨텍스트를 제공합니다. ctx 객체는 다음과 같은 주요 기능을 포함합니다:
- addIssue 메소드: 유효성 검사에서 문제가 발견되었을 때, 해당 문제를 추가하는 메소드입니다.
- path 속성: 현재 유효성 검사에서의 경로를 나타냅니다.
Zod로 정의된 formSchema
Zod를 사용하여 formSchema를 정의합니다. 이 스키마는 입력된 데이터의 구조와 각 필드의 유효성 검사를 정의합니다.
flatten 함수
flatten은 Zod의 에러 객체를 간단한 구조로 변환하는 메소드입니다. Zod의 유효성 검사에서 반환된 에러 객체는 다소 복잡할 수 있는데, flatten을 사용하면 이 에러 객체를 더 쉽게 처리하고 출력할 수 있는 형식으로 변환할 수 있습니다.
<>
: 이 괄호는 제네릭 괄호(generic brackets)라고 불리며, TypeScript에서 제네릭 타입을 정의할 때 사용됩니다.