Skip to content

Latest commit

Β 

History

History
474 lines (366 loc) Β· 21.5 KB

functions.md

File metadata and controls

474 lines (366 loc) Β· 21.5 KB

μ†Œκ°œ (Introduction)

ν•¨μˆ˜λŠ” JavaScript둜 된 λͺ¨λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œμ˜ 기본적인 ꡬ성 μš”μ†Œμž…λ‹ˆλ‹€. JavaScript ν•¨μˆ˜λŠ” 좔상화 계측을 κ΅¬μΆ•ν•˜κ±°λ‚˜ 클래슀 λͺ¨λ°©, 정보 은닉, λͺ¨λ“ˆμ— λŒ€ν•œ 방법을 μ œκ³΅ν•©λ‹ˆλ‹€. TypeScriptμ—λŠ” 클래슀, λ„€μž„μŠ€νŽ˜μ΄μŠ€, λͺ¨λ“ˆμ΄ μžˆμ§€λ§Œ, ν•¨μˆ˜λŠ” μ—¬μ „νžˆ 이 일을 μ–΄λ–»κ²Œ ν•  것인지λ₯Ό μ„€λͺ…ν•˜λŠ” 데 μžˆμ–΄ 핡심 역할을 μˆ˜ν–‰ν•©λ‹ˆλ‹€. TypeScriptμ—μ„œλŠ” ν‘œμ€€ JavaScript ν•¨μˆ˜κ°€ μž‘μ—…μ„ μˆ˜μ›”ν•˜κ²Œ ν•˜λ„λ‘ λͺ‡ 가지 μƒˆλ‘œμš΄ κΈ°λŠ₯을 μΆ”κ°€ν•©λ‹ˆλ‹€.

ν•¨μˆ˜ (Function)

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

JavaScriptμ—μ„œμ˜ 이 두 가지 방법에 λŒ€ν•œ μ˜ˆμ‹œλ₯Ό λΉ λ₯΄κ²Œ λ‹€μ‹œ λ³΄κ² μŠ΅λ‹ˆλ‹€:

// κΈ°λͺ… ν•¨μˆ˜
fucntion 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 Parameter)

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μ—μ„œλ„ 선택적 λ§€κ°œλ³€μˆ˜λ₯Ό μ›ν•œλ‹€λ©΄ λ§€κ°œλ³€μˆ˜ 이름 끝에 ? λ₯Ό λΆ™μž„μœΌλ‘œμ¨ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έ μ˜ˆμ‹œλ‘œ 성을 선택적 λ§€κ°œλ³€μˆ˜λ‘œ ν•˜λŠ” 경우λ₯Ό λ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€:

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");         // 정확함

μ–΄λŠ 선택적 λ§€κ°œλ³€μˆ˜λ“  λ°˜λ“œμ‹œ λ§€κ°œλ³€μˆ˜ μ •μ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€. lastName λŒ€μ‹  firstName을 μ„ νƒμ μœΌλ‘œ ν•˜κ³  μ‹Άλ‹€λ©΄ λ§€κ°œλ³€μˆ˜μ˜ μˆœμ„œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•©λ‹ˆλ‹€.

TypeScriptμ—μ„œλŠ” μœ μ €κ°€ 값을 μ œκ³΅ν•˜μ§€ μ•Šκ±°λ‚˜ undefined둜 ν–ˆμ„ λ•Œμ— 할당될 λ§€κ°œλ³€μˆ˜μ˜ 값을 μ •ν•΄ 놓을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 이것을 κΈ°λ³Έ-μ΄ˆκΈ°ν™” λ§€κ°œλ³€μˆ˜λΌκ³  ν•©λ‹ˆλ‹€. 이전 μ˜ˆμ‹œμ—μ„œ lastName을 "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(" ");
}

// employeeName 은 "Joseph Samuel Lucas MacKinzie" κ°€ λ κ²ƒμž…λ‹ˆλ‹€.
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜λŠ” 선택적 λ§€κ°œλ³€μˆ˜λ“€μ˜ 수λ₯Ό λ¬΄ν•œμœΌλ‘œ μ·¨κΈ‰ν•©λ‹ˆλ‹€. λ‚˜λ¨Έμ§€ λ§€κ°œλ³€μˆ˜λ‘œ μΈμžλ“€μ„ λ„˜κ²¨μ€„ λ•ŒλŠ” 당신이 μ›ν•˜λŠ” 만큼 λ„˜κ²¨ 쀄 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€; 아무것도 λ„˜κ²¨μ£Όμ§€ μ•Šμ„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬λŠ” μƒλž΅ λΆ€ν˜Έ (...) λ’€μ˜ μ΄λ¦„μœΌλ‘œ μ „λ‹¬λœ 인자 배열을 λΉŒλ“œν•˜μ—¬ ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

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

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

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

this

this κ°€ JavaScriptμ—μ„œ μ–΄λ–»κ²Œ μ“°μ΄λŠ”μ§€ μ•„λŠ” 것은 μΌμ’…μ˜ ν†΅κ³Όμ˜λ‘€μž…λ‹ˆλ‹€. TypeScriptλŠ” JavaScript의 μƒμœ„ μ§‘ν•©μ΄λ―€λ‘œ TypeScript κ°œλ°œμžλ“€ μ—­μ‹œ thisκ°€ μ–΄λ–»κ²Œ μ“°μ΄λŠ”μ§€ λ˜λŠ” thisκ°€ 잘λͺ» 쓰일 λ•Œλ₯Ό λ°œκ²¬ν•˜λŠ” 방법을 배울 ν•„μš”κ°€ μžˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆλ„ TypeScriptλŠ” λͺ‡ 가지 κΈ°μˆ λ“€λ‘œ 잘λͺ»λœ this μ‚¬μš©μ„ μž‘μ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€. λ§Œμ•½ JavaScriptμ—μ„œ thisκ°€ μ–΄λ–»κ²Œ λ™μž‘ν•˜λŠ”μ§€ μ•Œκ³  μ‹Άλ‹€λ©΄ λ¨Όμ € Yehuda Katz의 κΈ€ JavaScript ν•¨μˆ˜ 호좜과 "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κ°€ 자기 μžμ‹ μ„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μž„μ„ μ£Όλͺ©ν•΄ μ£Όμ„Έμš”. 이 예제λ₯Ό μž‘λ™μ‹œν‚€λ©΄ κΈ°λŒ€ν–ˆλ˜ 경보 μ°½ λŒ€μ‹  였λ₯˜κ°€ λ°œμƒν•  κ²ƒμž…λ‹ˆλ‹€. createCardPicker에 μ˜ν•΄ μƒμ„±λœ ν•¨μˆ˜μ—μ„œ μ‚¬μš© 쀑인 thisκ°€ deck 객체가 μ•„λ‹Œ window에 μ„€μ •λ˜μ—ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. cardPicker()의 자체적인 호좜 λ•Œλ¬Έμ— 생긴 μΌμž…λ‹ˆλ‹€. μ΅œμƒμœ„ λ ˆλ²¨μ—μ„œμ˜ λΉ„-λ©”μ„œλ“œ λ¬Έλ²•μ˜ ν˜ΈμΆœμ€ thisλ₯Ό window둜 ν•©λ‹ˆλ‹€. (Note: strict modeμ—μ„œλŠ” thisκ°€ window λŒ€μ‹  undefined κ°€ λ©λ‹ˆλ‹€. )

이 λ¬Έμ œλŠ” λ‚˜μ€‘μ— μ‚¬μš©ν•  ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜κΈ° 전에 바인딩을 μ•Œλ§žκ²Œ ν•˜λŠ” κ²ƒμœΌλ‘œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 λ°©λ²•λŒ€λ‘œλΌλ©΄ λ‚˜μ€‘μ— μ‚¬μš©ν•˜λŠ” 방법에 상관없이 원본 deck 객체λ₯Ό κ³„μ†ν•΄μ„œ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄, ν•¨μˆ˜ ν‘œν˜„μ‹μ„ ES6의 ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œ λ°”κΏ€ κ²ƒμž…λ‹ˆλ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” ν•¨μˆ˜κ°€ 호좜 된 곳이 μ•„λ‹Œ ν•¨μˆ˜κ°€ μƒμ„±λœ μͺ½μ˜ thisλ₯Ό μΊ‘μ²˜ν•©λ‹ˆλ‹€:

let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        // NOTE: μ•„λž«μ€„μ€ ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œμ¨, '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 λ§€κ°œλ³€μˆ˜ (this parameter)

λΆˆν–‰νžˆλ„ 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),
    // NOTE: μ•„λž˜ ν•¨μˆ˜λŠ” 이제 calleeκ°€ λ°˜λ“œμ‹œ 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둜 ν‘œμ‹œλ₯Ό ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

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

this: voidλŠ” addClickListenerκ°€ onclick이 thisνƒ€μž…μ„ μš”κ΅¬ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜κ°€ 될 κ²ƒμœΌλ‘œ μ˜ˆμƒν•˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. 두 번째둜, 호좜 μ½”λ“œλ₯Ό this둜 ν‘œμ‹œν•©λ‹ˆλ‹€.

class Handler {
    info: string;
    onClickBad(this: Handler, e: Event) {
        // 이런, `this`κ°€ μ—¬κΈ°μ„œ μ“°μ΄λŠ”κ΅°μš”. 이 μ½œλ°±μ„ μ“°λ©΄ λŸ°νƒ€μž„μ—μ„œ μΆ©λŒμ„ μΌμœΌν‚€κ² κ΅°μš”
        this.info = e.message;
    }
}
let h = new Handler();
uiElement.addClickListener(h.onClickBad); // 였λ₯˜!

this둜 ν‘œμ‹œλ₯Ό ν•œ μƒνƒœμ—μ„œ onClickBadκ°€ λ°˜λ“œμ‹œ Handler의 μΈμŠ€ν„΄μŠ€λ‘œμ¨ ν˜ΈμΆœλ˜μ–΄μ•Ό 함을 λͺ…μ‹œν•΄ μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€. 그러면 TypeScriptλŠ” addClickListenerκ°€ this: voidλ₯Ό κ°–λŠ” ν•¨μˆ˜λ₯Ό ν•„μš”λ‘œ ν•œλ‹€λŠ” 것을 κ°μ§€ν•©λ‹ˆλ‹€. 였λ₯˜λ₯Ό 고치기 μœ„ν•΄ this의 νƒ€μž…μ„ λ°”κΏ”μ€λ‹ˆλ‹€:

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

onClickGood이 this νƒ€μž…μ„ void둜 μ§€μ •ν•˜κ³  있기 λ•Œλ¬Έμ— addClickListener둜 λ„˜κ²¨μ§€λŠ”λ° μ ν•©ν•©λ‹ˆλ‹€. λ¬Όλ‘ , 이것이 this.infoλ₯Ό μ“Έ 수 μ—†λŠ” 것을 μ˜λ―Έν•˜κΈ°λ„ ν•©λ‹ˆλ‹€. λ§Œμ•½ 당신이 this.infoκΉŒμ§€ μ›ν•œλ‹€λ©΄ ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•  κ²λ‹ˆλ‹€:

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

μ΄λŸ¬ν•œ μž‘μ—…μ€ ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μ™ΈλΆ€μ˜ thisλ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— κ°€λŠ₯ν•˜λ―€λ‘œ this: void일 κ²ƒμœΌλ‘œ κΈ°λŒ€ν•˜λŠ” 무언가라면 전달에 λ¬Έμ œκ°€ μ—†μŠ΅λ‹ˆλ‹€. Handler νƒ€μž… κ°μ²΄λ§ˆλ‹€ ν•˜λ‚˜μ˜ ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μž‘μ„±λœλ‹€λŠ” 점이 λ‹¨μ μž…λ‹ˆλ‹€. 반면, λ©”μ„œλ“œλ“€μ€ ν•˜λ‚˜λ§Œ μž‘μ„±λ˜μ–΄ Handler의 ν”„λ‘œν† νƒ€μž…μ— λΆ™μŠ΅λ‹ˆλ‹€. 그듀은 Handler νƒ€μž…μ˜ λͺ¨λ“  객체 간에 κ³΅μœ λ©λ‹ˆλ‹€.

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

JavaScriptλŠ” 본질적으둜 맀우 동적인 μ–Έμ–΄μž…λ‹ˆλ‹€. ν•˜λ‚˜μ˜ JavaScript ν•¨μˆ˜κ°€ μ „λ‹¬λœ 인자의 ν˜•νƒœμ— 따라 λ‹€λ₯Έ νƒ€μž…μ˜ 객체듀을 λ°˜ν™˜ν•˜λŠ” 것은 ν”ν•œ μΌμž…λ‹ˆλ‹€.

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

function pickCard(x): any {
    // μΈμžκ°€ λ°°μ—΄ λ˜λŠ” 객체인지 확인
    // λ§Œμ•½ κ·Έλ ‡λ‹€λ©΄, deck이 주어지고 cardλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // 그렇지 μ•Šλ‹€λ©΄ κ·Έλƒ₯ 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);

μ—¬κΈ° μ‚¬μš©μžκ°€ μ „λ‹¬ν•˜λŠ” 것에 따라 두 가지 λ‹€λ₯Έ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€. μ‚¬μš©μžκ°€ deck을 μ˜λ―Έν•˜λŠ” 객체 값을 μ „λ‹¬ν•œλ‹€λ©΄ ν•¨μˆ˜κ°€ μΉ΄λ“œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. μ‚¬μš©μžκ°€ μΉ΄λ“œλ₯Ό μ„ νƒν•˜λ©΄ μ„ νƒν•œ μΉ΄λ“œκ°€ 무엇인지 λŒ€λ‹΅ν•΄ μ€λ‹ˆλ‹€. ν•˜μ§€λ§Œ νƒ€μž… μ‹œμŠ€ν…œμ—μ„œ 이것을 μ–΄λ–»κ²Œ κ΅¬ν˜„ν•  κ²ƒμž…λ‹ˆκΉŒ?

정닡은 μ˜€λ²„λ‘œλ“œ λͺ©λ‘μœΌλ‘œ λ™μΌν•œ ν•¨μˆ˜μ— 닀쀑 ν•¨μˆ˜ νƒ€μž…μ„ μ œκ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ€ μ»΄νŒŒμΌλŸ¬κ°€ ν•¨μˆ˜ ν˜ΈμΆœλ“€μ„ ν•΄κ²°ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μ˜€λ²„λ‘œλ“œ λͺ©λ‘μœΌλ‘œ 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 {
    // μΈμžκ°€ λ°°μ—΄ λ˜λŠ” 객체인지 확인
    // λ§Œμ•½ κ·Έλ ‡λ‹€λ©΄, deck이 주어지고 cardλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // 그렇지 μ•Šλ‹€λ©΄ κ·Έλƒ₯ 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);

이 λ³€ν™”λ₯Ό 톡해, μ˜€λ²„λ‘œλ“œλŠ” pickCard ν•¨μˆ˜μ— λŒ€ν•΄ νƒ€μž… 검사 ν˜ΈμΆœμ„ μ œκ³΅ν•©λ‹ˆλ‹€.

μ»΄νŒŒμΌλŸ¬κ°€ μ•Œλ§žμ€ νƒ€μž… 검사λ₯Ό ν•˜κΈ° μœ„ν•΄μ„œ, JavaScript와 λΉ„μŠ·ν•œ ν”„λ‘œμ„ΈμŠ€λ₯Ό λ”°λ¦…λ‹ˆλ‹€. μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ—μ„œ 첫 번째 μ˜€λ²„λ‘œλ“œλ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ 제곡된 λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ €κ³  μ‹œλ„ν•©λ‹ˆλ‹€. λ§Œμ•½ μΌμΉ˜ν•˜κ²Œ λœλ‹€λ©΄ ν•΄λ‹Ή μ˜€λ²„λ‘œλ“œλ₯Ό μ•Œλ§žμ€ μ˜€λ²„λ‘œλ“œλ‘œ μ„ νƒν•˜μ—¬ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 이유둜 κ°€μž₯ ꡬ체적인 것뢀터 μ˜€λ²„λ‘œλ“œ λ¦¬μŠ€νŒ…μ„ ν•˜λŠ” 것이 μΌλ°˜μ μž…λ‹ˆλ‹€.

μœ„ μ˜ˆμ œμ—μ„œ function pickCard(x): anyλŠ” μ˜€λ²„λ‘œλ“œ λͺ©λ‘μ— ν•΄λ‹Ήλ˜μ§€ μ•ŠμŒμ„ μœ μ˜ν•˜μ„Έμš”, κ·Έλž˜μ„œ 두 가지 μ˜€λ²„λ‘œλ“œλ§Œμ„ κ°€μ§‘λ‹ˆλ‹€: 객체λ₯Ό λ°›λŠ”κ²ƒ ν•˜λ‚˜μ™€ 숫자λ₯Ό λ°›λŠ” 것 ν•˜λ‚˜. λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜ νƒ€μž…μœΌλ‘œ pickCardλ₯Ό ν˜ΈμΆœν•˜λŠ” 것은 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.