[TS] 함수

ClassBinu·2024년 3월 26일

함수

JS에서 함수는 함수 외부 변수를 참조할 수 있음. 이걸 '변수를 capture한다'고 표현

let z = 100;

function addToZ(x, y) {
  return x + y + z;
}

함수 타이핑

  • 파라미터에 타입 지정
  • 함수 반환 타입 지정(단, TS는 반환문을 보고 반환 타입 파악하므로 반환 타입 생략 가능)
function add(x: number, y: number): number {
  return x + y;
}

let myAdd = function(x: number, y: number): number { return x + y };

캡처된 변수는 타입에 반영되지 않음.

함수 타입

함수의 매개변수와 반환값에 타입을 주는 게 아니라 함수 자체에 타입 적용

let myAdd: (x: number, y: number) => number = 
    function(x: number, y: number): number { return x + y; };

타입 추론

TS 컴파일러는 타입을 추론한다. 이런걸 contextual typing라고 함.

선택적 매개변수

// 옵셔널 지정
function buildName(firstName: string, lastName?: string)

// 기본값 지정
// 이건 매개변수가 undefiend일 때도 해당
function buildName(firstName: string, lastName = "Smith")

나머지 매개변수

function buildName(firstName: string, ...resfOfName: string[]) {
	return firstName + " " + restOfName.join(" ");
}

나머지 매개변수는 선택적 매개변수들의 수를 무한으로 취급

this

this는 함수가 호출될 때 정해지는 변수
즉, 함수가 실행되는 콘텍스트를 알아야 this를 알 수 있다.

최상위 레벨에서 비-메서드(함수) 호출의 경우 this는 window
(단, strict mode에서는 undefiend)

화살표 함수의 this

화살표 함수의 this는 호출된 곳이 아닌 함수가 생성된 쪽의 this를 캡처한다.

class Counter {
  constructor() {
    this.count = 0;
  }

  start() {
    setInterval(() => {
      this.count++;
      console.log(this.count);
    }, 1000);
  }
}

const myCounter = new Counter();
myCounter.start();

일반 함수 this

function showCount() {
  console.log(this.count);
}

const obj = {
  count: 5,
  showCount: showCount
};

obj.showCount(); // 5
showCount(); // undefined 또는 브라우저 환경에서는 window.count

화살표 함수 this

const obj = {
  count: 5,
  showCount: function() {
    setTimeout(() => {
      console.log(this.count);
    }, 1000);
  }
};

obj.showCount(); // 5, 화살표 함수는 showCount가 호출된 obj의 this를 상속받음

화살표 함수는 함수로 호출되더라도, 함수가 생성된 컨텍스트의 this에 바인딩된다.
즉, 화살표 함수가 정의될 때 주변 스코프의 this 값을 캡처하는 것

만약, setTinterval같은 비동기 함수에서 전통적인 함수를 콜백으로 쓰면 그 함수의 this는 전역 객체(엄격모드에서는 undefiend)를 가리키게 된다.

인스턴스 내부에서 this를 올바르게 참조하려면 화살표 함수를 써야 함.

일반 함수의 this는 정의가 아니라 호출될 때 결정된다는 것 기억하기
화살표 함수의 this 바인딩은 함수가 선언된 시점의 this를 캡처한다.

오버로드

같은 이름의 함수를 다른 매개변수 타입이나, 매개변수 개수에 따라 다르게 정의

자바스크립트는 동적인 언어이므로, 인자에 따라 다른 타입의 객체를 반환하는 건 흔하다.
그래서 이렇게 다르게 함수를 선언할 수 있음.

// 이거 2개가 오버로드 목록
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };

function pickCard(x: any): any {
    // 여기서 x의 타입에 따라 분기 처리를 하여 각 오버로드에 맞는 로직을 수행
    if (typeof x == "object") {
        // 첫 번째 오버로드에 해당하는 로직
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    else if (typeof x == "number") {
        // 두 번째 오버로드에 해당하는 로직
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

컴파일러는 오버로드 목록에서 첫 번째 선언으로 함수 호출 시도, 이후 순차적
따라서 구체적인 것부터 오버로드 리스팅하는 것이 일반적

0개의 댓글