미새문지

24.08.05 day40 IIFE, Type과 Interface의 차이점 본문

개발 TIL

24.08.05 day40 IIFE, Type과 Interface의 차이점

문미새 2024. 8. 5. 22:25
728x90

즉시 실행 함수(IIFE, Immediately Invoked Function Expression)

IIFE는 정의되자마자 실행되는 자바스크립트 함수이며, 이는 자바스크립트에서 흔히 사용되는 패턴으로, 함수의 스코프를 이용해 변수를 캡슐화하거나 초기화 코드를 즉시 실행할 때 유용하다.

(function() {  }) (); 또는 (function() {  } ());이 기본 형태이다.

IIFE의 장점

  1. 스코프 캡슐화: IIFE 내부에서 정의된 변수는 외부에서 접근할 수 없으므로 전역 스코프를 오염시키지 않는다.
  2. 모듈화: IIFE를 사용하면 모듈 단위로 코드를 분리하여 관리할 수 있다.
  3. 익명 함수: IIFE는 이름이 없는 익명 함수로 정의되므로 함수 이름을 정의하지 않아도 된다.
  4. 초기화 코드: 페이지 로드 시점에서 실행되어야 하는 초기화 코드를 작성할 때 유용하다.

예제

IIFE를 사용하여 변수 counter를 캡슐화하고, 해당 변수를 증가시키는 예제

const counter = (function() {
    let count = 0; // 이 변수는 IIFE 내부에서만 접근 가능

    return {
        increment: function() {
            count++;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        getCount: function() {
            return count;
        }
    };
})();

console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount());  // 2
console.log(counter.decrement()); // 1

IIFE는 자바크스립트의 함수 스코프와 클로저를 활용하는 좋은 방법 중 하나로, 다양한 상황에서 코드의 안정성과 유지보수성을 높이는 데 기여할 수 있다.

 

일반 함수와 IIFE의 차이

1. 실행 시점

  • 일반 함수: 정의한 후 호출할 때까지 실행되지 않는다.
function regularFunction() {
    console.log("This is a regular function.");
}

regularFunction(); // 함수를 호출해야 실행됩니다.
  • IIFE: 정의되자마자 즉시 실행된다.
(function() {
    console.log("This is an IIFE.");
})();
// 함수 정의와 동시에 실행됩니다.

 

2. 사용 목적

  • 일반 함수: 주로 재사용 가능한 코드 블록을 만들기 위해 사용되며, 여러 번 호출할 수 있다.
function add(a, b) {
    return a + b;
}

console.log(add(2, 3)); // 5
console.log(add(4, 5)); // 9
  • IIFE: 주로 초기화 코드, 한 번만 실행되어야 하는 코드를 작성할 때 사용되며, 변수의 스코프를 제한하거나 라이브러리 코드에서 많이 사용된다.
(function() {
    const message = "This is a one-time message.";
    console.log(message);
})();

// message 변수는 IIFE 내부에 캡슐화되어 외부에서 접근할 수 없습니다.

 

3. 스코프 관리

  • 일반 함수: 전역 스코프에 변수를 선언할 수 있고, 스코프 관리가 덜 엄격하다.
let count = 0;

function increment() {
    count++;
}

increment();
console.log(count); // 1
  • IIFE: 지역 스코프를 제공하여 변수의 생명 주기를 함수 내부로 제한하고, 전역 스코프 오염을 방지한다.
(function() {
    let count = 0;

    function increment() {
        count++;
        console.log(count);
    }

    increment(); // 1
    increment(); // 2
})();

// count 변수는 IIFE 내부에 캡슐화되어 외부에서 접근할 수 없습니다.

 

4. 코드 모듈화와 캡슐화

  • 일반 함수: 모듈화보다는 주로 기능 단위의 코드 재사용을 목표로 한다.
function showMessage(message) {
    console.log(message);
}

showMessage("Hello, World!");
  • IIFE: 코드를 모듈화하고, 변수나 함수가 전역 스코프에 노출되지 않도록 캡슐화하는 데 주로 사용된다.
(function() {
    const privateVariable = "I'm private";

    function privateFunction() {
        console.log(privateVariable);
    }

    privateFunction();
})();
// privateVariable과 privateFunction은 IIFE 외부에서 접근할 수 없습니다.
  • 일반 함수는 여러 번 호출될 수 있고, 주로 재사용 가능한 코드 블록을 만드는 데 사용된다.
  • IIFE는 정의되자마자 즉시 실행되며, 주로 초기화 코드나 한 번만 실행되어야 하는 코드를 작성하고, 스코프를 캡슐화하여 전역 변수를 오염시키지 않기 위해 사용된다.

이러한 차이점으로 인해 IIFE는 초기화 코드, 라이브러리 코드, 그리고 전역 스코프를 오염시키지 않고 지역 스코프에서 변수를 관리해야 하는 상황에서 특히 유용할 수 있다.


Type과 Interface의 차이점

타입스크립트에서 Type과 Interface는 모두 객체의 형태를 정의하는 데 사용된다.

둘 다 유사한 기능을 제공하지만, 일부 차이점이 있어 각자의 장점과 사용 사례에 따라 선택적으로 사용할 수 있다.

 

1. 기본 사용법

  • Interface: 객체의 형태를 정의하기 위해 주로 사용
interface Person {
    name: string;
    age: number;
}

const person: Person = {
    name: "John",
    age: 30
};
  • Type: 객체의 형태를 정의하거나, 기본 타입에 별칭을 부여하기 위해 사용
type Person = {
    name: string;
    age: number;
}

const person: Person = {
    name: "John",
    age: 30
};

 

2. 확장 (Extending)

  • Interface: 다른 인터페이스를 상속받아 확장할 수 있다.
interface Person {
    name: string;
    age: number;
}

interface Employee extends Person {
    employeeId: number;
}

const employee: Employee = {
    name: "Jane",
    age: 25,
    employeeId: 123
};
  • Type: 교차 타입(intersection types)을 사용하여 확장할 수 있다.
type Person = {
    name: string;
    age: number;
}

type Employee = Person & {
    employeeId: number;
}

const employee: Employee = {
    name: "Jane",
    age: 25,
    employeeId: 123
};

 

3. 합집합 (Union Types)

  • Type: 유니온 타입을 사용하여 여러 타입 중 하나를 정의할 수 있다.
type Status = "success" | "error" | "loading";

function printStatus(status: Status) {
    console.log(status);
}

printStatus("success"); // 정상 동작
  • Interface: 인터페이스는 유니온 타입을 직접적으로 지원하진 않지만, 대신 유니온 타입을 가진 프로퍼티를 정의할 수 있다.
interface SuccessResponse {
    status: "success";
    data: string;
}

interface ErrorResponse {
    status: "error";
    error: string;
}

type Response = SuccessResponse | ErrorResponse;

function handleResponse(response: Response) {
    if (response.status === "success") {
        console.log(response.data);
    } else {
        console.log(response.error);
    }
}

 

 

그 외 차이점

  • 동일한 이름의 인터페이스를 여러 번 정의하면 TypeScript는 이를 자동으로 병합하지만, 타입 별칭은 병합되지 않으며, 동일한 이름으로 두 번 정의할 수 없다.
  • 타입 별칭은 객체 타입 이외에도, 원시 타입, 유니온 타입, 튜플 등을 정의할 수 있다.

요약

  • Interface: 객체의 형태를 정의하는 데 주로 사용되며, 선언 병합 기능을 제공하여 여러 번 정의할 수 있다. 상속을 통해 확장할 수 있다.
  • Type: 객체의 형태를 정의할 뿐만 아니라, 원시 타입, 유니온 타입, 튜플 등의 별칭을 정의할 수 있다. 교차 타입을 통해 확장할 수 있지만, 선언 병합은 지원하지 않는다.

둘 중 어떤 것을 사용할지는 프로젝트의 요구 사항과 개인의 선호에 따라 결정될 수 있으며, 객체의 형태를 정의하고 확장하는 데 집중한다면 인터페이스를 사용하는 것이 좋고, 다양한 타입을 조합하고 유니온 타입 등을 많이 사용한다면 타입 별칭을 사용하는 것이 유리할 수 있다.

728x90