Skip to content

Latest commit

Β 

History

History
483 lines (370 loc) Β· 21.9 KB

Functions.md

File metadata and controls

483 lines (370 loc) Β· 21.9 KB

μ†Œκ°œ (Introduction)

ν•¨μˆ˜λŠ” JavaScript의 λͺ¨λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν•˜λŠ” κΈ°λ³Έ μš”μ†Œμž…λ‹ˆλ‹€.
ν΄λž˜μŠ€λŠ” 좔상화 계측, 클래슀, 정보 은닉 및 λͺ¨λ“ˆμ„ κ΅¬μΆ•ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.
TypeScriptμ—μ„œλŠ” ν΄λž˜μŠ€μ™€ λ„€μž„ 슀페이슀 그리고 λͺ¨λ“ˆμ΄ μžˆμ§€λ§Œ ν•¨μˆ˜λŠ” κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  μž‘μ—… 방법을 μ„€λͺ…ν•˜λŠ” 데 μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€.
λ˜ν•œ TypeScriptλŠ” ν‘œμ€€ JavaScript κΈ°λŠ₯에 λͺ‡κ°€μ§€ μƒˆλ‘œμš΄ κΈ°λŠ₯을 μΆ”κ°€ν•˜μ—¬ μž‘μ—…μ„ 더 μ‰½κ²Œ ν•΄ μ€λ‹ˆλ‹€.

ν•¨μˆ˜ (Functions)

JavaScript와 λ§ˆμ°¬κ°€μ§€λ‘œ TypeScript ν•¨μˆ˜λŠ” κΈ°λͺ… ν•¨μˆ˜ λ˜λŠ” 읡λͺ… ν•¨μˆ˜λ‘œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
이λ₯Ό 톡해 API의 ν•¨μˆ˜ λͺ©λ‘μ„ μž‘μ„±ν•˜λ“  λ‹€λ₯Έ ν•¨μˆ˜μ— 전달할 μΌνšŒμ„± ν•¨μˆ˜μ΄λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— κ°€μž₯ μ ν•©ν•œ μ ‘κ·Ό 방법을 선택할 수 μžˆμŠ΅λ‹ˆλ‹€.

이 두가지 μ ‘κ·Ό 방식이 JavaScriptμ—μ„œ μ–΄λ–»κ²Œ λ³΄μ΄λŠ”μ§€ λΉ λ₯΄κ²Œ μš”μ•½ν•˜λ©΄:

// κΈ°λͺ… ν•¨μˆ˜
function add(x, y) {
    return x + y;
}

// 읡λͺ… ν•¨μˆ˜
let myAdd = function(x, y) { return x + y; };

JavaScriptμ—μ„œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ ν•¨μˆ˜λŠ” ν•¨μˆ˜ λ³Έλ¬Έ μ™ΈλΆ€μ˜ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
κ·Έλ ‡κ²Œ ν•  λ•Œ μ΄λŸ¬ν•œ λ³€μˆ˜λ“€μ„ capture라고 λ§ν•©λ‹ˆλ‹€.
이 κΈ°λ²•μ˜ μ‚¬μš© 방법과 μ‚¬μš©ν•  λ•Œμ˜ 절좩 사항을 μ΄ν•΄ν•˜λŠ” 것은 이번 μž₯의 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜μ§€λ§Œ
캑처의 λ©”μ»€λ‹ˆμ¦˜μ΄ JavaScript와 TypeScript에 μ–Όλ§ˆλ‚˜ μ€‘μš”ν•œ 뢀뢄인지 ν™•μ‹€νžˆ 이해해야 ν•©λ‹ˆλ‹€.

let z = 100;

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

ν•¨μˆ˜μ˜ νƒ€μž… (Function Types)

ν•¨μˆ˜ μž‘μ„±ν•˜κΈ° (Typing the function)

μ•žμ—μ„œ μ‚΄νŽ΄λ³Έ κ°„λ‹¨ν•œ μ˜ˆμ œμ— νƒ€μž…μ„ μΆ”κ°€ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

function add(x: number, y: number): number {
    return x + y;
}

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

각 λ§€κ°œλ³€μˆ˜μ— νƒ€μž…μ„ μΆ”κ°€ ν•œ λ‹€μŒ ν•¨μˆ˜ μžμ²΄μ— νƒ€μž…μ„ μΆ”κ°€ν•˜μ—¬ λ°˜ν™˜ νƒ€μž…μ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
TypeScriptλŠ” 리턴문λ₯Ό 보고 λ°˜ν™˜ νƒ€μž…μ„ νŒŒμ•…ν•  수 있기 λ•Œλ¬Έμ— λŒ€λΆ€λΆ„ μ„ νƒμ μœΌλ‘œ λ°˜ν™˜ νƒ€μž…μ„ μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν•¨μˆ˜ νƒ€μž… μž‘μ„±ν•˜κΈ° (Writing the function type)

이제 ν•¨μˆ˜λ₯Ό μž‘μ„±ν–ˆμœΌλ―€λ‘œ ν•¨μˆ˜ νƒ€μž…μ˜ 각 뢀뢄을 μ‚΄νŽ΄λ³΄λ©΄μ„œ ν•¨μˆ˜μ˜ 전체 νƒ€μž…μ„ μž‘μ„±ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

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

ν•¨μˆ˜μ˜ νƒ€μž…μ€ λ‘κ°œμ˜ 파트둜 λ‚˜λ‰©λ‹ˆλ‹€: 인수의 νƒ€μž…κ³Ό λ°˜ν™˜ νƒ€μž….
전체 ν•¨μˆ˜ νƒ€μž…μ„ μž‘μ„±ν•  λ•Œ 두 νŒŒνŠΈκ°€ λͺ¨λ‘ ν•„μš”ν•©λ‹ˆλ‹€.
λ§€κ°œλ³€μˆ˜ νƒ€μž…κ³Ό 같이 λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ„ κΈ°λ‘ν•˜μ—¬ 각 λ§€κ°œλ³€μˆ˜μ— 이름과 νƒ€μž…μ„ μ§€μ •ν•©λ‹ˆλ‹€.
이 이름은 가독성을 돕기 μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€.

μœ„μ˜ μ½”λ“œλ₯Ό λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

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

λ§€κ°œλ³€μˆ˜ νƒ€μž…μ΄ μ •λ ¬λ˜μ–΄ μžˆλŠ” ν•œ ν•¨μˆ˜μ˜ νƒ€μž…μ— λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ³΅ν•˜λŠ” 이름에 관계 없이 λ§€κ°œλ³€μˆ˜ νƒ€μž…μ΄ μœ νš¨ν•œ νƒ€μž…μœΌλ‘œ κ°„μ£Όλ©λ‹ˆλ‹€.

두 번째 νŒŒνŠΈλŠ” λ°˜ν™˜ νƒ€μž…μž…λ‹ˆλ‹€.
λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜ νƒ€μž… 사이에 ꡡ은 ν™”μ‚΄ν‘œ(=>)λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°˜ν™˜ νƒ€μž…μ„ λͺ…ν™•ν•˜κ²Œ ν•©λ‹ˆλ‹€.
μ•žμ„œ μ–ΈκΈ‰ν•œ κ²ƒμ²˜λŸΌ 이것은 ν•¨μˆ˜ νƒ€μž…μ˜ ν•„μˆ˜μ μΈ λΆ€λΆ„μ΄λ―€λ‘œ ν•¨μˆ˜κ°€ 값을 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ—λŠ” λ°˜ν™˜ 값을 남겨 두지 μ•Šκ³  voidλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

μ£Όμ˜μ‚¬ν•­, λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜ νƒ€μž…λ§Œ ν•¨μˆ˜ νƒ€μž…μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.
캑처된 λ³€μˆ˜λŠ” νƒ€μž…μ— λ°˜μ˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
μ‹€μ œλ‘œ 캑처된 λ³€μˆ˜λŠ” ν•¨μˆ˜μ˜ "μˆ¨κ²¨μ§„ μƒνƒœ"의 일뢀이며 ν•΄λ‹Ή APIλ₯Ό κ΅¬μ„±ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

νƒ€μž… μΆ”λ‘  (Inferring the types)

예λ₯Ό λ“€μ–΄ TypeScript μ»΄νŒŒμΌλŸ¬λŠ” ν•œμͺ½μ—λŠ” νƒ€μž…μ΄ μžˆμ§€λ§Œ λ‹€λ₯Έ ν•œμͺ½μ— νƒ€μž…μ΄ μ—†λŠ” 경우 κ·Έ νƒ€μž…μ„ 이해할 수 μ—†λ‹€λŠ” 것을 μ•Œκ²Œ λ©λ‹ˆλ‹€:

// myAddλŠ” μ™„λ²½ν•˜κ²Œ ν•¨μˆ˜ νƒ€μž…μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€.
let myAdd = function(x: number, y: number): number { return  x + y; };

// λ§€κ°œλ³€μˆ˜ 'x'와 'y'μ—λŠ” number νƒ€μž…μ΄ μžˆμŠ΅λ‹ˆλ‹€.
let myAdd: (baseValue: number, increment: number) => number =
    function(x, y) { return x + y; };

이것을 νƒ€μž… μΆ”λ‘ μ˜ ν•œ μ’…λ₯˜μΈ "상황적 타이핑(Contextual Typing)"이라고 ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 ν”„λ‘œκ·Έλž¨μ„ 계속 μœ μ§€ν•˜λŠ” 데 λ“œλŠ” λ…Έλ ₯을 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

선택적 λ§€κ°œλ³€μˆ˜μ™€ κΈ°λ³Έ λ§€κ°œλ³€μˆ˜ (Optional and Default Parameters)

TypeScriptμ—μ„œλŠ” λͺ¨λ“  λ§€κ°œλ³€μˆ˜κ°€ ν•¨μˆ˜μ— ν•„μš”ν•˜λ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.
null λ˜λŠ” undefinedκ°€ μ£Όμ–΄μ§ˆ 수 μ—†λ‹€λŠ” 것을 μ˜λ―Έν•˜λŠ” 것이 μ•„λ‹ˆλΌ ν•¨μˆ˜κ°€ 호좜될 λ•Œ μ»΄νŒŒμΌλŸ¬κ°€ 각 λ§€κ°œλ³€μˆ˜μ— 값을 μ œκ³΅ν–ˆλŠ”μ§€ ν™•μΈν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
λ˜ν•œ μ»΄νŒŒμΌλŸ¬λŠ” μ΄λŸ¬ν•œ λ§€κ°œλ³€μˆ˜λ“€μ΄ ν•¨μˆ˜λ‘œ μ „λ‹¬λ˜λŠ” μœ μΌν•œ λ§€κ°œλ³€μˆ˜λΌκ³  κ°€μ •ν•©λ‹ˆλ‹€.
κ°„λ‹¨νžˆ λ§ν•΄μ„œ ν•¨μˆ˜μ— 주어진 인수의 μˆ˜λŠ” κ·Έ ν•¨μˆ˜μ—μ„œ κΈ°λŒ€ν•˜λŠ” λ§€κ°œλ³€μˆ˜μ˜ μˆ˜μ™€ μΌμΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

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

let result1 = buildName("Bob");                  // 였λ₯˜, λ„ˆλ¬΄ 적은 λ§€κ°œλ³€μˆ˜
let result2 = buildName("Bob", "Adams", "Sr.");  // 였λ₯˜, λ„ˆλ¬΄ λ§Žμ€ λ§€κ°œλ³€μˆ˜
let result3 = buildName("Bob", "Adams");         // μ•„, λ”± λ§žμŠ΅λ‹ˆλ‹€

JavaScriptμ—μ„œ λͺ¨λ“  λ§€κ°œλ³€μˆ˜λŠ” 선택 사항이며 λ§€κ°œλ³€μˆ˜λ₯Ό μ›ν•˜λŠ” λŒ€λ‘œ μ‚¬μš©ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
κ·Έλ ‡κ²Œ 되면 κ·Έ λ§€κ°œλ³€μˆ˜λ“€μ˜ 값은 undefinedμž…λ‹ˆλ‹€. TypeScriptμ—μ„œ 선택적인 λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ μ„ νƒμ μœΌλ‘œ μ‚¬μš©ν•˜λ €λŠ” λ§€κ°œλ³€μˆ˜μ˜ 끝에 ?λ₯Ό μΆ”κ°€ν•˜μ„Έμš”.

예λ₯Ό λ“€μ–΄ μœ„μ—μ„œ μ‚¬μš©ν•œ lastName λ§€κ°œλ³€μˆ˜λ₯Ό μ„ νƒμ μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€:

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

let result1 = buildName("Bob");                  // μ˜¬λ°”λ₯΄κ²Œ μž‘λ™ν•©λ‹ˆλ‹€
let result2 = buildName("Bob", "Adams", "Sr.");  // 였λ₯˜, λ„ˆλ¬΄ λ§Žμ€ λ§€κ°œλ³€μˆ˜
let result3 = buildName("Bob", "Adams");         // μ•„, λ”± λ§žμŠ΅λ‹ˆλ‹€

λͺ¨λ“  선택적 λ§€κ°œλ³€μˆ˜λŠ” ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ₯Ό 따라와야 ν•©λ‹ˆλ‹€.
last name λŒ€μ‹  first name을 선택적 λ§€κ°œλ³€μˆ˜λ‘œ λ§Œλ“€κ³  μ‹Άλ‹€λ©΄ ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ μˆœμ„œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•©λ‹ˆλ‹€.
즉 λͺ©λ‘μ˜ first name을 λ§ˆμ§€λ§‰μ— λ„£μ–΄μ•Όν•©λ‹ˆλ‹€.

TypeScriptμ—μ„œ μ‚¬μš©μžκ°€ λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ³΅ν•˜μ§€ μ•Šκ±°λ‚˜ μ‚¬μš©μžκ°€ λŒ€μ‹  undefinedλ₯Ό μ „λ‹¬ν•˜λ”λΌλ„ λ§€κ°œλ³€μˆ˜κ°€μ— ν• λ‹Ήλ˜λŠ” 값을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
이것을 κΈ°λ³Έ λ§€κ°œλ³€μˆ˜(default-initialized parameters)라고 ν•©λ‹ˆλ‹€.

μ•žμ˜ 예제λ₯Ό 따라 last name의 기본값을 "Smith"둜 μ„€μ •ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.

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

let result1 = buildName("Bob");                  // μ˜¬λ°”λ₯΄κ²Œ μž‘λ™ν•˜λ©° "Bob Smith"λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€
let result2 = buildName("Bob", undefined);       // μ—¬μ „νžˆ μž‘λ™ν•˜λ©° "Bob Smith"λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
let result3 = buildName("Bob", "Adams", "Sr.");  // 였λ₯˜, λ„ˆλ¬΄ λ§Žμ€ λ§€κ°œλ³€μˆ˜
let result4 = buildName("Bob", "Adams");         // μ•„, λ”± λ§žμŠ΅λ‹ˆλ‹€

ν•„μˆ˜ λ§€κ°œλ³€μˆ˜μ˜ 뒀에 μ˜€λŠ” κΈ°λ³Έ λ§€κ°œλ³€μˆ˜λŠ” 선택적 λ§€κ°œλ³€μˆ˜λ‘œ μ·¨κΈ‰λ˜μ–΄ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ 선택적 λ§€κ°œλ³€μˆ˜μ²˜λŸΌ μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
이것은 선택적 λ§€κ°œλ³€μˆ˜μ™€ ν›„ν–‰ κΈ°λ³Έ λ§€κ°œλ³€μˆ˜κ°€ ν•΄λ‹Ή νƒ€μž…μ˜ 곡톡점을 κ³΅μœ ν•œλ‹€λŠ” 것을 μ˜λ―Έν•˜λ―€λ‘œ

λ‘˜ λ‹€

function buildName(firstName: string, lastName?: string) {
    // ...
}

그리고

function buildName(firstName: string, lastName = "Smith") {
    // ...
}

(firstName: string, lastName?: string) => string λ™μΌν•œ νƒ€μž…μ„ κ³΅μœ ν•©λ‹ˆλ‹€.
lastName의 κΈ°λ³Έ 값은 νƒ€μž…μ—μ„œ 사라지고 λ§€κ°œλ³€μˆ˜κ°€ 선택 μ‚¬ν•­μ΄λΌλŠ” μ‚¬μ‹€λ§Œ λ‚¨κ²¨μ‘ŒμŠ΅λ‹ˆλ‹€.

일반 선택적 λ§€κ°œλ³€μˆ˜μ™€ 달리 κΈ°λ³Έ λ§€κ°œλ³€μˆ˜λŠ” ν•„μˆ˜ λ§€κ°œλ³€μˆ˜ 뒀에 λ‚˜μ˜¬ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
κΈ°λ³Έ λ§€κ°œλ³€μˆ˜κ°€ ν•„μˆ˜ λ§€κ°œλ³€μˆ˜ μ•žμ— μ˜€λŠ” 경우 μ‚¬μš©μžλŠ” λͺ…μ‹œμ μœΌλ‘œ undefinedλ₯Ό μ „λ‹¬ν•˜μ—¬ κΈ°λ³Έ μ΄ˆκΈ°ν™”λœ 값을 가져와야 ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ firstName에 κΈ°λ³Έ μ΄ˆκΈ°ν™”λ§Œ μžˆλŠ” λ§ˆμ§€λ§‰ 예제λ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

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

let result1 = buildName("Bob");                  // 였λ₯˜, λ„ˆλ¬΄ 적은 λ§€κ°œλ³€μˆ˜
let result2 = buildName("Bob", "Adams", "Sr.");  // 였λ₯˜, λ„ˆλ¬΄ λ§Žμ€ λ§€κ°œλ³€μˆ˜
let result3 = buildName("Bob", "Adams");         // μ’‹μ•„μš” "Bob Adams"λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€
let result4 = buildName(undefined, "Adams");     // μ’‹μ•„μš” "Will Adams"λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€

λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜ (Rest Parameters)

ν•„μˆ˜ λ§€κ°œλ³€μˆ˜μ™€ 선택적 λ§€κ°œλ³€μˆ˜ 그리고 κΈ°λ³Έ λ§€κ°œλ³€μˆ˜ λͺ¨λ‘ 곡톡점이 ν•˜λ‚˜ μžˆμŠ΅λ‹ˆλ‹€: ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ λ§€κ°œλ³€μˆ˜μ— λŒ€ν•΄ μ΄μ•ΌκΈ°ν•©λ‹ˆλ‹€.
λ•Œλ‘œλŠ” μ—¬λŸ¬ λ§€κ°œλ³€μˆ˜λ₯Ό 그룹으둜 μ‚¬μš©ν•˜κ±°λ‚˜ ν•¨μˆ˜κ°€ λ§ˆμ§€λ§‰μœΌλ‘œ κ°€μ Έμ˜¬ λ§€κ°œλ³€μˆ˜μ˜ 수λ₯Ό λͺ¨λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
JavaScriptμ—μ„œλŠ” λͺ¨λ“  ν•¨μˆ˜ λ³Έλ¬Έμ—μ„œ λ³Ό 수 μžˆλŠ” argumentsλ₯Ό μ‚¬μš©ν•˜μ—¬ 인수λ₯Ό 직접 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

TypeScriptμ—μ„œλŠ” λ‹€μŒκ³Ό 같은 인수λ₯Ό λ³€μˆ˜λ‘œ ν•¨κ»˜ λͺ¨μ„μˆ˜ μžˆμŠ΅λ‹ˆλ‹€:

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

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

λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜λŠ” λ¬΄ν•œμ μΈ 수의 선택적 λ§€κ°œλ³€μˆ˜λ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€.
Rest λ§€κ°œλ³€μˆ˜μ— 인수λ₯Ό 전달할 λ•ŒλŠ” μ›ν•˜λŠ” 만큼 μ‚¬μš©ν•  수 있으며 심지어 톡과할 수 μ—†μŠ΅λ‹ˆλ‹€.
μ»΄νŒŒμΌλŸ¬λŠ” μ€„μž„ν‘œ (...) λ‹€μŒμ— μ „λ‹¬λœ μΈμˆ˜λ“€μ„ 배열을 μž‘μ„±ν•˜μ—¬ ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ€„μž„ν‘œ(...)λŠ” λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜κ°€ μžˆλŠ” ν•¨μˆ˜μ˜ νƒ€μž…μ—λ„ μ‚¬μš©λ©λ‹ˆλ‹€:

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

let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;

this

JavaScriptμ—μ„œ thisλ₯Ό μ‚¬μš©λ²•μ„ λ°°μš°λŠ” 것은 μΌμ’…μ˜ 톡과 μ˜λ‘€μž…λ‹ˆλ‹€.
TypeScriptλŠ” JavaScript의 μƒμœ„ 집합이기 λ•Œλ¬Έμ— TypeScript κ°œλ°œμžλ“€λ„ this을 μ‚¬μš©ν•˜λŠ” 방법과 μ˜¬λ°”λ₯΄κ²Œ μ‚¬μš©λ˜κ³  μžˆμ§€ μ•Šμ„ λ•Œλ₯Ό μ°Ύμ•„λ‚΄λŠ” 방법을 λ°°μ›Œμ•Ό ν•©λ‹ˆλ‹€.
JavaScriptμ—μ„œ thisκ°€ μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ μ•Œμ•„μ•Ό ν•œλ‹€λ©΄ Yehuda Katz의 Understanding JavaScript Function Invocation and "this"λ₯Ό λ¨Όμ € μ½μ–΄λ³΄μ„Έμš”.
Yehuda의 κΈ€μ—λŠ” this의 λ‚΄λΆ€ λ™μž‘μ„ 잘 μ„€λͺ…ν•˜κΈ° λ•Œλ¬Έμ— μ—¬κΈ°μ„œλŠ” 기본적인 λ‚΄μš©λ§Œ λ‹€λ£° κ²ƒμž…λ‹ˆλ‹€.

this와 ν™”μ‚΄ν‘œ ν•¨μˆ˜ (this and arrow functions)

JavaScriptμ—μ„œ thisλŠ” ν•¨μˆ˜κ°€ 호좜될 λ•Œ μ„€μ •λ˜λŠ” λ³€μˆ˜μž…λ‹ˆλ‹€.
맀우 κ°•λ ₯ν•˜κ³  μœ μ—°ν•œ κΈ°λŠ₯μ΄μ§€λ§Œ ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ” 상황에 λŒ€ν•΄ 항상 μ•Œκ³  μžˆμ–΄μ•Ό ν•˜λŠ” μ‹œκ°„μ΄ λ“­λ‹ˆλ‹€.
특히 ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ ν•¨μˆ˜λ₯Ό 인수둜 전달할 λ•Œ μ•…λͺ… 높을 μ •λ„λ‘œ ν˜Όλž€μŠ€λŸ½μŠ΅λ‹ˆλ‹€.

예제λ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€:

let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        return function() {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

createCardPickerλŠ” 자체적으둜 ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
예제λ₯Ό μ‹€ν–‰ν•˜λ €κ³  ν•˜λ©΄ alert λŒ€μ‹  였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.
createCardPicker에 μ˜ν•΄ μƒμ„±λœ ν•¨μˆ˜μ—μ„œ μ‚¬μš©λ˜λŠ” thisκ°€ deck 객체 λŒ€μ‹ μ— window둜 μ„€μ •λ˜μ–΄ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.
μ™œλƒν•˜λ©΄ cardPicker()λŠ” 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
이와 같이 μ΅œμƒμœ„ λΉ„-λ©”μ„œλ“œ ꡬ문 ν˜ΈμΆœμ€ this에 windowλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
(μ£Όμ˜μ‚¬ν•­ : 엄격λͺ¨λ“œ(strict mode)μ—μ„œ thisλŠ” windowλ³΄λ‹€λŠ” undefinedκ°€ 될 κ²ƒμž…λ‹ˆλ‹€).

λ‚˜μ€‘μ— μ‚¬μš©ν•  ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜κΈ° 전에 ν•¨μˆ˜μ— μ˜¬λ°”λ₯Έ thisκ°€ μ—°κ²°λ˜λ„λ‘ν•˜μ—¬ 이λ₯Ό ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ ‡κ²Œν•˜λ©΄ λ‚˜μ€‘μ— μ–΄λ–»κ²Œ μ‚¬μš©λ˜λ“  상관없이 μ›λž˜μ˜ deck객체λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
이λ₯Ό μœ„ν•΄ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ ECMAScript 6의 ν™”μ‚΄ν‘œ ꡬ문으둜 λ³€κ²½ν•˜μ—¬ μ‚¬μš©ν•©λ‹ˆλ‹€.
ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” 호좜된 곳이 μ•„λ‹Œ ν•¨μˆ˜κ°€ 생성 된 κ³³μ—μ„œ thisλ₯Ό μΊ‘μ²˜ν•©λ‹ˆλ‹€:

let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        // 주의: μ•„λž˜ 쀄은 이제 ν™”μ‚΄ν‘œ ν•¨μˆ˜μž…λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ 'this'λ₯Ό μΊ‘μ²˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

더 쒋은 점은 μ»΄νŒŒμΌλŸ¬μ— --noImplicitThis μ‹ ν˜Έλ₯Ό λ„˜κ²¨μ£Όλ©΄ TypeScriptκ°€ μ‹€μˆ˜λ₯Ό ν–ˆμ„ λ•Œ κ²½κ³ λ₯Ό ν•©λ‹ˆλ‹€.
this.suits[pickedSuit]μ—μ„œ thisλŠ” any νƒ€μž…μž…λ‹ˆλ‹€.

this parameters

λΆˆν–‰νžˆλ„ this.suits [pickedSuit]의 νƒ€μž…μ€ μ—¬μ „νžˆanyμž…λ‹ˆλ‹€.
μ™œλƒν•˜λ©΄ thisλŠ” 객체 λ¦¬ν„°λŸ΄ λ‚΄λΆ€μ˜ ν•¨μˆ˜ ν‘œν˜„μ‹μ—μ„œ μ™”κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λͺ…μ‹œμ μœΌλ‘œ this λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

this λ§€κ°œλ³€μˆ˜λŠ” ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ—μ„œ 처음 λ‚˜μ˜€λŠ” κ°€μ§œ λ§€κ°œλ³€μˆ˜μž…λ‹ˆλ‹€:

function f(this: void) {
    // 이 λΆ„λ¦¬λœ ν•¨μˆ˜μ—μ„œ 'this'λ₯Ό μ‚¬μš©ν•  수 μ—†λŠ”μ§€ ν™•μΈν•΄λ³΄μ„Έμš”.
}

μœ„μ˜ μ˜ˆμ œμ—μ„œ Card와 Deck에 λͺ‡ 가지 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μΆ”κ°€ν•˜μ—¬ νƒ€μž…μ„ 더 λͺ…ν™•ν•˜κ³  μ‰½κ²Œ μž¬μ‚¬μš©ν•˜κΈ° μ‰½κ²Œ λ§Œλ“€ 수 μžˆλ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€

interface Card {
    suit: string;
    card: number;
}
interface Deck {
    suits: string[];
    cards: number[];
    createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    // μ£Όμ˜μ‚¬ν•­ : 이 ν•¨μˆ˜λŠ” 이제 λ°˜λ“œμ‹œ Deck νƒ€μž…μ΄μ–΄μ•Όν•©λ‹ˆλ‹€
    createCardPicker: function(this: Deck) {
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

이제 TypeScriptλŠ”createCardPickerκ°€ Deck κ°μ²΄μ—μ„œ 호좜될 κ²ƒμœΌλ‘œ μ˜ˆμƒν•©λ‹ˆλ‹€.
즉 thisλŠ” anyκ°€ μ•„λ‹Œ Deck νƒ€μž…μž…λ‹ˆλ‹€. λ”°λΌμ„œ --noImplicitThisλŠ” 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ½œλ°±μ—μ„œμ˜ this λ§€κ°œλ³€μˆ˜ (this parameters in callbacks)

ν•¨μˆ˜λ₯Ό λ‚˜μ€‘μ— ν˜ΈμΆœν•  λΌμ΄λΈŒλŸ¬λ¦¬μ— 전달할 λ•Œ μ½œλ°±μ—μ„œ thisλ₯Ό μ‚¬μš©ν•˜μ—¬ 였λ₯˜κ°€ λ°œμƒν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
μ™œλƒν•˜λ©΄ μ½œλ°±μ„ ν˜ΈμΆœν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬κ°€ ν‘œμ€€ ν•¨μˆ˜μ²˜λŸΌ ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έμ— thisλŠ” undefinedκ°€ 될 κ²ƒμž…λ‹ˆλ‹€.

λ•Œλ•Œλ‘œ this λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 콜백 였λ₯˜λ₯Ό 방지할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 첫 번째, 라이브러리 μž‘μ„±μžλŠ” 콜백 νƒ€μž…μ— thisλ₯Ό μ‚¬μš©ν•˜μ—¬ annotateλ₯Ό 달아야 ν•©λ‹ˆλ‹€:

interface UIElement {
    addClickListener(onclick: (this: void, e: Event) => void): void;
}

this : voidλŠ” addClickListenerκ°€ onclick이 this νƒ€μž…μ„ ν•„μš”λ‘œ ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜λΌλŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

두 번째, thisλ₯Ό μ‚¬μš©ν•˜μ—¬ 호좜 μ½”λ“œμ™€ ν•¨κ»˜ annotateλ₯Ό 달아야 ν•©λ‹ˆλ‹€:

class Handler {
    info: string;
    onClickBad(this: Handler, e: Event) {
        // 이런, μ—¬κΈ°μ„œ thisλ₯Ό μ‚¬μš©ν–ˆμ–΄μš”. 이 μ½œλ°±μ„ μ‚¬μš©ν•˜λ©΄ 좩돌으둜 λŸ°νƒ€μž„ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.
        this.info = e.message;
    }
}
let h = new Handler();
uiElement.addClickListener(h.onClickBad); // 였λ₯˜!

thisκ°€ annotatedλ˜μ–΄ 있으면 onClickBadλŠ” λ°˜λ“œμ‹œ Handler의 μΈμŠ€ν„΄μŠ€μ—μ„œ ν˜ΈμΆœλ˜μ–΄μ•Όν•œλ‹€λŠ” 것을 λͺ…μ‹œν•΄μ•Ό ν•©λ‹ˆλ‹€.
그런 λ‹€μŒ TypeScriptλŠ” addClickListener에 this : voidκ°€ μžˆλŠ” ν•¨μˆ˜κ°€ ν•„μš”ν•˜λ‹€λŠ” 것을 λ°œκ²¬ν•©λ‹ˆλ‹€.
였λ₯˜λ₯Ό ν•΄κ²°ν•˜λ €λ©΄ this의 νƒ€μž…μ„ μˆ˜μ •ν•˜μ„Έμš”:

class Handler {
    info: string;
    onClickGood(this: void, e: Event) {
        // this의 νƒ€μž…μ΄ void이기 λ•Œλ¬Έμ— μ—¬κΈ°μ„œλŠ” μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€!
        console.log('clicked!');
    }
}
let h = new Handler();
uiElement.addClickListener(h.onClickGood);

onClickGoodλŠ” this의 νƒ€μž…μ„ void둜 μ§€μ •ν•˜κΈ° λ•Œλ¬Έμ— addClickListener에 전달할 수 μžˆμŠ΅λ‹ˆλ‹€.
λ¬Όλ‘  thisλŠ” λ˜ν•œ this.infoλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
두 가지 λͺ¨λ‘λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€:

class Handler {
    info: string;
    onClickGood = (e: Event) => { this.info = e.message }
}

이것은 ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ thisλ₯Ό μΊ‘μ²˜ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— νš¨κ³Όμ μž…λ‹ˆλ‹€.
λ•Œλ¬Έμ— κΈ°λŒ€ν•˜λŠ” 것 같이 항상 this : voidλ₯Ό λ„˜κ²¨μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€.

단점은 Handler νƒ€μž…μ˜ κ°μ²΄λ§ˆλ‹€ ν•˜λ‚˜μ˜ ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μƒμ„±λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
λ°˜λ©΄μ— λ©”μ„œλ“œλŠ” ν•œ 번만 λ§Œλ“€μ–΄μ§€κ³  ν•Έλ“€λŸ¬μ˜ ν”„λ‘œν†  νƒ€μž…μ— μ†Œμ†λ©λ‹ˆλ‹€.
μ΄λŸ¬ν•œ κ°μ²΄λŠ” ν•Έλ“€λŸ¬ νƒ€μž…μ˜ λͺ¨λ“  객체 사이에 κ³΅μœ λ©λ‹ˆλ‹€.

μ˜€λ²„λ‘œλ“œ (Overloads)

JavaScriptλŠ” 본질적으둜 맀우 동적인 μ–Έμ–΄μž…λ‹ˆλ‹€.
단일 JavaScript ν•¨μˆ˜κ°€ μ „λ‹¬λœ 인수의 ν˜•νƒœλ₯Ό 기반으둜 μ„œλ‘œ λ‹€λ₯Έ νƒ€μž…μ˜ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 것은 λ“œλ¬Έ 일이 μ•„λ‹™λ‹ˆλ‹€.

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

function pickCard(x): any {
    // 객체 / λ°°μ—΄λ‘œ μž‘μ—…ν•˜κ³  μžˆλŠ”μ§€ ν™•μΈν•΄λ³΄μ„Έμš”
    // κ·Έλ ‡λ‹€λ©΄ 그것듀은 덱을 μ£Όκ³  μ‚¬μš©μžλŠ” μΉ΄λ“œλ₯Ό 선택할 κ²ƒμž…λ‹ˆλ‹€.
    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);

μ—¬κΈ°μ„œ pickCard ν•¨μˆ˜λŠ” μ‚¬μš©μžκ°€ 무엇을 μ „λ‹¬ν–ˆλŠ”μ§€μ— 따라 두 개의 μ„œλ‘œ λ‹€λ₯Έ λ‚΄μš©μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.
μ‚¬μš©μžκ°€ deckλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 객체λ₯Ό μ „λ‹¬ν•˜λ©΄ ν•¨μˆ˜κ°€ cardλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
μ‚¬μš©μžκ°€ cardλ₯Ό μ„ νƒν•˜λ©΄ 그듀이 μ„ νƒν•œ cardλ₯Ό μ•Œλ €μ€λ‹ˆλ‹€.
ν•˜μ§€λ§Œ 이것을 μ–΄λ–»κ²Œ νƒ€μž… μ‹œμŠ€ν…œμ— μ„€λͺ…ν• κΉŒμš”?

이에 λŒ€ν•œ λŒ€λ‹΅μ€ μ˜€λ²„λ‘œλ“œ λͺ©λ‘κ³Ό λ™μΌν•œ ν•¨μˆ˜μ— λŒ€ν•œ μ—¬λŸ¬ ν•¨μˆ˜ νƒ€μž…μ„ μ œκ³΅ν•˜λŠ” 것이닀.
이 λͺ©λ‘μ€ μ»΄νŒŒμΌλŸ¬κ°€ ν•¨μˆ˜ ν˜ΈμΆœμ„ ν•΄κ²°ν•˜λŠ” 데 μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€.
pickCardκ°€ 받아듀일 수 μžˆλŠ” 것과 그것이 λ°˜ν™˜ν•˜λŠ” 것을 κΈ°μˆ ν•œ μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ„ μž‘μ„±ν•΄ λ³΄μ„Έμš”.

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 {
    // 객체 / λ°°μ—΄λ‘œ μž‘μ—…ν•˜κ³  μžˆλŠ”μ§€ ν™•μΈν•΄λ³΄μ„Έμš”
    // κ·Έλ ‡λ‹€λ©΄ 그것듀은 덱을 μ£Όκ³  μ‚¬μš©μžλŠ” μΉ΄λ“œλ₯Ό 선택할 κ²ƒμž…λ‹ˆλ‹€.
    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);

이런 λ³€ν™”λ‘œ 인해 μ˜€λ²„λ‘œλ“œκ°€ pickCard ν•¨μˆ˜μ— λŒ€ν•œ νƒ€μž…-체크 ν˜ΈμΆœμ„ μ œκ³΅ν•©λ‹ˆλ‹€.

μ»΄νŒŒμΌλŸ¬κ°€ μ˜¬λ°”λ₯Έ νƒ€μž… 검사λ₯Ό μ„ νƒν•˜κΈ° μœ„ν•΄ κΈ°λ³Έ JavaScript와 λΉ„μŠ·ν•œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.
μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ„ μ‚΄νŽ΄λ³΄κ³  제곡된 λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 첫 번째 μ˜€λ²„λ‘œλ“œ μ‹œλ„λ₯Ό κ³„μ†ν•©λ‹ˆλ‹€.
μΌμΉ˜ν•˜λŠ” 것을 찾으면 이 μ˜€λ²„λ‘œλ“œλ₯Ό μ˜¬λ°”λ₯Έ μ˜€λ²„λ‘œλ“œλ‘œ μ„ νƒν•©λ‹ˆλ‹€.
μ΄λŸ¬ν•œ 이유 λ•Œλ¬Έμ— 주문이 λ§Žμ•„μ§€λ©΄ κ°€μž₯ ꡬ체적인 κ²ƒμ—μ„œ κ°€μž₯ 덜 ꡬ체적인 κ²ƒμœΌλ‘œ μ˜€λ²„λ‘œλ“œν•©λ‹ˆλ‹€.

function pickCard (x) : any 쑰각은 μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ˜ 일뢀가 μ•„λ‹ˆλ―€λ‘œ 두 개의 μ˜€λ²„λ‘œλ“œλ§Œ μžˆμŠ΅λ‹ˆλ‹€:
ν•˜λ‚˜λŠ” 객체λ₯Ό μ·¨ν•˜κ³  ν•˜λ‚˜λŠ” 숫자λ₯Ό μ·¨ν•©λ‹ˆλ‹€.
pickCardλ₯Ό λ‹€λ₯Έ 맀개 λ³€μˆ˜ νƒ€μž…κ³Ό ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.