본문 바로가기

TypeScript/Handbook

[TypeScript] 05. Functions

원문 : https://www.typescriptlang.org/docs/handbook/functions.html


Introduction

함수는 JavaScript 에서 가장 기본이되는 개념이다. 함수를 통해, 추상화 계층을 정의 하거나, 클래스를 구현하거나, 정보를 숨기거나 모듈화 를 할 수 있다. TypeScript에서는 이미 모듈, class, namespace가 따로 존재하지만 함수는 여전히 어떤 행위에 대한 정의를 하고, 이를 JavaScript 보다 편하게 구현 할 수 있도록 한다.


Functions

JavaScript와 마찬가지로 함수 명을 명시하는 기명 함수(named function) 표현식, 함수 명이 없는 무기명 함수(anonymous function) 표현식 모두 사용 가능하며, 함수 블록 밖에 있는 변수를 참조 할 수 있다.

// 기명 함수 (Named function)
function add(x, y) {
    return x + y;
}

// 무기명 함수 (Anonymous function)
let myAdd = function(x, y) { return x + y; };

// 함수 외부의 변수 참조
let z = 100;
function addToZ(x, y) {
    return x + y + z;
}


Function Types

typing the function

각 표현식 별로 아래와 같이 함수 type을 정의 할 수 있다.

// function [함수명] ([파라미터]: [파라미터 타입]): [return 타입]
function add(x: number, y: number): number {
    return x + y;
}

// function ([파라미터]: [파라미터 타입]): [return 타입]
let myAdd = function(x: number, y: number): number { return x + y; };

let myAdd2 (baseValue: number, increment: number) => number = function (x: number, y: number): number {return x + y};
let myAdd3 = function (x: number, y: number): number {return x + y};
let myAdd4 (baseValue: number, increment: number) => number = function (x, y) {return x + y};

return type 이 없으면 void 로 적는다.


Optional and Default Parameters

JavaScript와 다르게 TypeScript 에서 모든 파라미터는 필수 요소로 간주 된다. 따라서 선택적으로 Parameter를 입력하거나, 아니면 parameter를 입력 받지 못했을 때 기본 값을 적용 하고 싶은 경우 아래와 같이 처리 한다.

원래 함수

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // error, too few parameters
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");         // ah, just right

파라미터를 선택적으로 입력 하고 싶은 경우

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");                  // works correctly now
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");         // ah, just right

파라미터에 기본 값을 적용 하고 싶은 경우

function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

let result1 = buildName("Bob");                  // works correctly now, returns "Bob Smith"
let result2 = buildName("Bob", undefined);       // still works, also returns "Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result4 = buildName("Bob", "Adams");         // ah, just right


Rest Parameters

파라미터의 수가 정해져 있지 않은 경우 "..." 를 붙여 파라미터그룹을 받을 수 있다.

// 첫번째 파라미터는 firstName, 그 이후 문자들은 restOfName 변수에 배열 형태로 담김
function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");


Overloads

JavaScript는 아래 예 와 같이 투입되는 아규먼트의 타입에따라 그 결과 타입이 다른 경우가 흔하게 있을 정도로 태생부터 동적 언어 이다.

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x): any {
    // 아규먼트가 Object / Array 타입이면 배열 중 랜덤으로 카드 한장을 뽑는다.
    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 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

TypeScript에서 함수 Overload를 작성하는 방법은, 아래와 같이 함수의 정의를 먼저 하고(인터페이스작성 하는 것 처럼) 실제 구현 코드를 작성한다.

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);




this

this에 대한 학습은 JavaScript를 공부하는데 있어서 통과 의례(?) 같은 과정이다. 어줍잖게 작성 하는 것 보다 원문에서 추천하는 링크를 남긴다.

Yehuda Katz’s Understanding JavaScript Function Invocation and “this”.





반응형

'TypeScript > Handbook' 카테고리의 다른 글

[TypeScript] 06. Generics  (0) 2018.10.23
[TypeScript] 04. Classes  (0) 2017.07.07
[TypeScript] 03. Interfaces  (0) 2017.05.04
[TypeScript] 02. 변수 선언  (0) 2017.04.25
[TypeScript] 01. Basic Types  (0) 2017.04.24