본문으둜 κ±΄λ„ˆλ›°κΈ°

🐀 Chapter 4: ν•¨μˆ˜μ™€ λ©”μ„œλ“œ

πŸ¦„ ν•¨μˆ˜ 선언문​

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λŠ” function ν‚€μ›Œλ“œλ‘œ λ§Œλ“œλŠ” ν•¨μˆ˜μ™€ => 기호둜 λ§Œλ“œλŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ 두 가지 μžˆλ‹€.
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜ 선언문은 μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜ μ„ μ–Έλ¬Έμ—μ„œ λ§€κ°œλ³€μˆ˜μ™€ ν•¨μˆ˜ λ°˜ν™˜κ°’μ— νƒ€μž… 주석을 λΆ™μ΄λŠ” λ‹€μŒ ν˜•νƒœλ‘œ κ΅¬μ„±λœλ‹€.
function add(a: number, b: number): number {
return a + b;
}

let result = add(1, 2);

πŸ“š λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ˜ νƒ€μž… 주석 μƒλž΅β€‹

  • ν•¨μˆ˜ μ„ μ–Έλ¬Έμ—μ„œλ„ λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ— λŒ€ν•œ νƒ€μž… 주석을 μƒλž΅ν•  수 μžˆλ‹€.
  • λ‹€λ§Œ, λ³€μˆ˜ λ•Œμ™€λŠ” 달리 ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…κ³Ό λ°˜ν™˜ νƒ€μž…μ„ μƒλž΅ν•˜λŠ” 것은 λ°”λžŒμ§ν•˜μ§€ μ•Šλ‹€. μ™œλƒν•˜λ©΄, νƒ€μž…μ΄ μƒλž΅λ˜μ–΄ 있으면 ν•¨μˆ˜μ˜ κ΅¬ν˜„ μ˜λ„λ₯Ό μ•ŒκΈ° μ–΄λ ΅κ³  잘λͺ» μ‚¬μš©ν•˜κΈ° 쉽기 λ•Œλ¬Έμ΄λ‹€.

πŸ“š void νƒ€μž…β€‹

  • 값을 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜λŠ” λ°˜ν™˜ νƒ€μž…μ΄ void이닀.
  • void νƒ€μž…μ€ ν•¨μˆ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€.
function printMe(name: string, age: number): void {
console.log(`name: ${name}, age: ${age}`);
}

πŸ“š ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜β€‹

  • λ³€μˆ˜μ— νƒ€μž…μ΄ μžˆλ“―μ΄ ν•¨μˆ˜ λ˜ν•œ νƒ€μž…μ΄ μžˆλŠ”λ°, ν•¨μˆ˜μ˜ νƒ€μž…μ„ ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λΌκ³  ν•œλ‹€.
(λ§€κ°œλ³€μˆ˜1νƒ€μž…, λ§€κ°œλ³€μˆ˜2νƒ€μž…[, ...]) => λ°˜ν™˜κ°’ νƒ€μž…
  • λ‹€μŒ printMe ν•¨μˆ˜λŠ” stringκ³Ό number νƒ€μž…μ˜ λ§€κ°œλ³€μˆ˜κ°€ 두 개 있고 λ°˜ν™˜ νƒ€μž…μ΄ void이닀.
  • λ”°λΌμ„œ ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λŠ” (string, number) => void 이닀.
let printMe: (string, number) => void = function (name: string, age: number): void {}
  • λ§Œμ•½ λ§€κ°œλ³€μˆ˜κ°€ μ—†μœΌλ©΄ λ‹¨μˆœνžˆ ()둜 ν‘œν˜„ν•œλ‹€. () => voidλŠ” λ§€κ°œλ³€μˆ˜λ„ μ—†κ³  λ°˜ν™˜κ°’λ„ μ—†λŠ” ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜μ΄λ‹€.

πŸ“š type ν‚€μ›Œλ“œλ‘œ νƒ€μž… 별칭 λ§Œλ“€κΈ°β€‹

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” typeμ΄λΌλŠ” ν‚€μ›Œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.
  • type ν‚€μ›Œλ“œλŠ” 기쑴에 μ‘΄μž¬ν•˜λŠ” νƒ€μž…μ„ λ‹¨μˆœνžˆ μ΄λ¦„λ§Œ λ°”κΏ”μ„œ μ‚¬μš©ν•  수 있게 ν•΄μ€€λ‹€.
  • μ΄λŸ¬ν•œ κΈ°λŠ₯을 νƒ€μž… 별칭(type alias)이라고 ν•œλ‹€.
type μƒˆλ‘œμš΄νƒ€μž… = κΈ°μ‘΄νƒ€μž…
  • (string, number) => void ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό stringNumberFuncμ΄λΌλŠ” μ΄λ¦„μœΌλ‘œ νƒ€μž… 별칭을 λ§Œλ“ λ‹€.
  • 이 별칭 덕뢄에 λ³€μˆ˜ f와 g에 νƒ€μž… 주석을 더 μˆ˜μ›”ν•˜κ²Œ 뢙일 수 μžˆλ‹€.
type stringNumberFunc = (string, number) => void;
let f: stringNumberFunc = function(a: string, b: number): void {}
let g: stringNumberFunc = function(c: string, d: number): void {}
  • ν•¨μˆ˜μ˜ νƒ€μž…, 즉 ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό λͺ…μ‹œν•˜λ©΄ λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜λ‚˜ νƒ€μž…, λ°˜ν™˜ νƒ€μž…μ΄ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 잘λͺ»μ„ 미연에 방지할 수 μžˆλ‹€.
// μƒλž΅...
let h: stringNumberFunc = function () {}
h(); // 2개의 μΈμˆ˜κ°€ ν•„μš”ν•œλ° 0개λ₯Ό κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.

πŸ“š undefined κ΄€λ ¨ 주의 사항​

  • undefined νƒ€μž…μ€ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ νƒ€μž… κ³„μΈ΅λ„μ—μ„œ λͺ¨λ“  νƒ€μž… 쀑 μ΅œν•˜μœ„ νƒ€μž…μ΄λ‹€.
  • λ‹€μŒμ€ undefinedλ₯Ό κ³ λ €ν•˜μ§€ μ•Šμ€ μ˜ˆμ΄λ‹€.
interface INameable {
name: string;
}

function getName(o: INameable) { return o.name; }

let n = getName(undefined); // 였λ₯˜ λ°œμƒ
console.log(n);
  • getName은 INameable νƒ€μž…μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μš”κ΅¬ν•˜μ§€λ§Œ, undefined ν˜ΈμΆœν•΄λ„ ꡬ문 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
  • 즉, undefinedλŠ” μ΅œν•˜μœ„ νƒ€μž…μ΄λ―€λ‘œ INameable을 μƒμ†ν•˜λŠ” μžμ‹ νƒ€μž…μœΌλ‘œ κ°„μ£Όν•œλ‹€.
  • ν•˜μ§€λ§Œ, μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.
  • λ‹€μŒμ€ undefinedλ₯Ό κ³ λ €ν•œ μ˜ˆμ΄λ‹€.
interface INameable {
name: string;
}

function getName(o: INameable) {
return o != undefined ? o.name : 'unknown name';
}

let n = getName(undefined);
console.log(n); // unknown name
console.log(getName({ name: 'Jack' })); // Jack
  • λ§Œμ•½ μΈν„°νŽ˜μ΄μŠ€μ— 선택 속성이 μžˆλ‹€λ©΄ λ‹€μŒκ³Ό 같이 κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.
interface IAgeable {
age?: number;
}

function getAge(o: IAgeable) {
return o != undefined && o.age ? o.age : 0;
}

console.log(getAge(undefined)); // 0
console.log(getAge(null)); // 0
console.log(getAge({ age: 32 })); // 32

πŸ“š 선택적 λ§€κ°œλ³€μˆ˜β€‹

  • ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ—λ„ λ‹€μŒμ²˜λŸΌ 이름 뒀에 λ¬ΌμŒν‘œλ₯Ό 뢙일 수 있으며, 이λ₯Ό 선택적 λ§€κ°œλ³€μˆ˜λΌκ³  ν•œλ‹€.
function fn(arg1: string, arg?: number): void {}
  • 선택적 λ§€κ°œλ³€μˆ˜λŠ” λ‹€μŒ μ½”λ“œμ—μ„œ ν•¨μˆ˜ ν˜ΈμΆœμ„ λͺ¨λ‘ κ°€λŠ₯ν•˜κ²Œ ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•œλ‹€.
function fn(arg1: string, arg?: number) { console.log(`arg: ${arg}`); }

fn('hello', 1); // arg: 1
fn('hello'); // arg: undefined
  • 선택적 λ§€κ°œλ³€μˆ˜κ°€ μžˆλŠ” ν•¨μˆ˜μ˜ μ‹œκ·Έλ‹ˆμ²˜λŠ” λ‹€μŒμ²˜λŸΌ νƒ€μž… 뒀에 λ¬ΌμŒν‘œλ₯Ό 뢙인닀.
type OptionalArgFunc = (string, number?) => void

πŸ¦„ ν•¨μˆ˜ ν‘œν˜„μ‹β€‹

πŸ“š ν•¨μˆ˜λŠ” 객체닀​

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜λŠ” Function 클래슀의 μΈμŠ€ν„΄μŠ€μ΄λ‹€.
  • λ‹€μŒ μ½”λ“œμ˜ addλŠ” ν•¨μˆ˜λ‘œμ„œ λ™μž‘ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.
let add = new Function('a', 'b', 'return a + b');
let result = add(1, 2);
console.log(result); // 3
  • add ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같은 ν˜•νƒœλ‘œλ„ κ΅¬ν˜„ν•  수 μžˆλ‹€.
let add2 = function(a, b) { 
return a + b;
}

console.log(add2(1, 2)); // 3
  • 이처럼 ν•¨μˆ˜ μ„ μ–Έλ¬Έμ—μ„œ ν•¨μˆ˜ 이름을 μ œμ™Έν•œ function(a, b) { return a + b; }와 같은 μ½”λ“œλ₯Ό ν•¨μˆ˜ ν‘œν˜„μ‹(function expression)이라고 ν•œλ‹€.

πŸ“š 일등 ν•¨μˆ˜β€‹

  • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄κ°€ 일등 ν•¨μˆ˜(first-class function) κΈ°λŠ₯을 μ œκ³΅ν•˜λ©΄ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° 언어라고 ν•œλ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 일등 ν•¨μˆ˜ κΈ°λŠ₯이 μžˆμœΌλ―€λ‘œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° 언어이닀.
  • 일당 ν•¨μˆ˜λž€, ν•¨μˆ˜μ™€ λ³€μˆ˜λ₯Ό κ΅¬λΆ„ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” μ˜λ―Έμ΄λ‹€.
  • 예λ₯Ό λ“€μ–΄ λ‹€μŒ μ½”λ“œμ—μ„œ fλŠ” let ν‚€μ›Œλ“œκ°€ μ•žμ— μžˆμœΌλ―€λ‘œ λ³€μˆ˜μ΄λ‹€. fλŠ” λ³€μˆ˜μ΄λ―€λ‘œ 값을 μ €μž₯ν•  수 μžˆλ‹€. λ³€μˆ˜ fμ—λŠ” a + b ν˜•νƒœμ˜ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ μ €μž₯ν–ˆλ‹€.
  • ν•˜μ§€λ§Œ fλŠ” λ³€μˆ˜μ΄λ―€λ‘œ 2ν–‰μ²˜λŸΌ a - b ν˜•νƒœμ˜ ν•¨μˆ˜ ν‘œν˜„μ‹λ„ μ €μž₯ν•  수 μžˆλ‹€.
let f = function(a, b) { return a + b; }
f = function(a, b) { return a - b; }
  • μ‹¬λ²Œ fκ°€ λ³€μˆ˜μΈμ§€ ν•¨μˆ˜μΈμ§€ 사싀상 ꡬ뢄할 수 μ—†λ‹€. 이것이 λ³€μˆ˜μ™€ ν•¨μˆ˜λ₯Ό μ°¨λ³„ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” μ˜λ―Έμ΄λ‹€.

πŸ“š ν‘œν˜„μ‹β€‹

  • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ ν‘œν˜„μ‹(expression)μ΄λΌλŠ” μš©μ–΄λŠ” λ¦¬ν„°λŸ΄, μ—°μ‚°μž, λ³€μˆ˜, ν•¨μˆ˜ 호좜 등이 λ³΅ν•©μ μœΌλ‘œ κ΅¬μ„±λœ μ½”λ“œ ν˜•νƒœλ₯Ό μ˜λ―Έν•œλ‹€.
  • 예λ₯Ό λ“€μ–΄, 1 + 2λŠ” 1 κ³Ό 2λΌλŠ” λ¦¬ν„°λŸ΄κ³Ό λ§μ…ˆ μ—°μ‚°μž +둜 κ΅¬μ„±λœ ν‘œν˜„μ‹μ΄λ‹€.

πŸ“š ν•¨μˆ˜ ν‘œν˜„μ‹β€‹

  • μ•žμ—μ„œ μž‘μ„±ν•œ λ³€μˆ˜ fμ—λŠ” function(a, b) { return a + b; }마치 κ°’μ²˜λŸΌ λŒ€μž…ν•˜λŠ”λ°, 이 function(a, b) { return a + b; } 뢀뢄을 ν•¨μˆ˜ ν‘œν˜„μ‹μ΄λΌκ³  ν•œλ‹€.

πŸ“š 계산법​

  • μ»΄νŒŒμΌλŸ¬λŠ” ν‘œν˜„μ‹μ„ λ§Œλ‚˜λ©΄ 계산법을 μ μš©ν•΄ μ–΄λ–€ 값을 λ§Œλ“œλŠ”λ° κ³„μ‚°λ²•μ—λŠ” μ‘°κΈ‰ν•œ 계산법과 λŠκΈ‹ν•œ(지연) 계산법 두 가지가 μžˆλ‹€.
  • μ»΄νŒŒμΌλŸ¬κ°€ 1 + 2λΌλŠ” ν‘œν˜„μ‹μ„ λ§Œλ‚˜λ©΄ μ‘°κΈ‰ν•œ 계산법을 μ μš©ν•΄ 3μ΄λΌλŠ” 값을 λ§Œλ“€κ³ , μ»΄νŒŒμΌλŸ¬κ°€ function(a, b) { return a + b; }λΌλŠ” ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ§Œλ‚˜λ©΄, μ‹¬λ²Œ a와 bκ°€ μ–΄λ–€ 값인지 μ•Œ 수 μ—†μ–΄μ„œ λŠκΈ‹ν•œ 계산법을 μ μš©ν•΄ 계산을 보λ₯˜ν•œλ‹€.

πŸ“š ν•¨μˆ˜ 호좜 μ—°μ‚°μžβ€‹

  • μ–΄λ–€ λ³€μˆ˜κ°€ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ‹΄κ³  μžˆλ‹€λ©΄, λ³€μˆ˜ 이름 뒀에 ν•¨μˆ˜ 호좜 μ—°μ‚°μž ()λ₯Ό λΆ™μ—¬μ„œ ν˜ΈμΆœν•  수 μžˆλ‹€.
let functionExpression = function(a, b) { return a + b; }
let value = functionExpression(1, 2); // (1, 2): ν•¨μˆ˜ 호좜 μ—°μ‚°μž
  • μ»΄νŒŒμΌλŸ¬λŠ” ν•¨μˆ˜ ν˜ΈμΆœλ¬Έμ„ λ§Œλ‚˜λ©΄ μ§€κΈˆκΉŒμ§€ 미뀘던 ν•¨μˆ˜ ν‘œν˜„μ‹μ— μ‘°κΈ‰ν•œ 계산법을 μ μš©ν•΄ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ κ°’μœΌλ‘œ λ°”κΎΌλ‹€. ( return 1 + 2 => return 3 )

πŸ“š 읡λͺ… ν•¨μˆ˜β€‹

  • ν•¨μˆ˜ ν‘œν˜„μ‹μ€ 사싀 λŒ€λΆ€λΆ„ μ–Έμ–΄μ—μ„œ μ–ΈκΈ‰λ˜λŠ” 읡λͺ… ν•¨μˆ˜(anonymous function)의 λ‹€λ₯Έ ν‘œν˜„μ΄λ‹€.
let value = (function(a, b) {return a + b; })(1, 2) // 3
  • λ‹€μŒ μ½”λ“œλŠ” μ•žμ˜ ν•œ μ€„κΉŒμ§€ μ½”λ“œλ₯Ό μ‰½κ²Œ λΆ„μ„ν•˜κ³ μž μ„Έ μ€„λ‘œ λ‚˜λˆˆ 것이닀.
let value = 
(function(a, b) { return a + b })
(1, 2) // 3
  • μ»΄νŒŒμΌλŸ¬λŠ” 2ν–‰μ˜ 읡λͺ… ν•¨μˆ˜ 뢀뢄에 게으λ₯Έ 계산법을 μ μš©ν•΄ κ·Έ μƒνƒœλ‘œ λ†”λ‘μ§€λ§Œ, κ³§λ°”λ‘œ 3ν–‰μ˜ ν•¨μˆ˜ 호좜 μ—°μ‚°μžλ₯Ό λ§Œλ‚˜λ―€λ‘œ 2ν–‰μ˜ ν•¨μˆ˜ λͺΈν†΅μ— μ‘°κΈ‰ν•œ 계산법을 μ μš©ν•΄ μ΅œμ’…μ μœΌλ‘œ 3μ΄λΌλŠ” 값을 λ§Œλ“€μ–΄ λ‚Έλ‹€.

πŸ“š const ν‚€μ›Œλ“œμ™€ ν•¨μˆ˜ ν‘œν˜„μ‹β€‹

  • ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ‹΄λŠ” λ³€μˆ˜λŠ” let λ³΄λ‹€λŠ” const ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•˜λŠ” 것이 λ°”λžŒμ§ν•˜λ‹€.
  • ν•¨μˆ˜ ν‘œν˜„μ‹μ„ 담은 λ³€μˆ˜λ₯Ό constν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•˜λ©΄, ν•¨μˆ˜ λ‚΄μš©μ΄ 이후에 μ ˆλŒ€λ‘œ λ°”λ€” 수 μ—†λ‹€.
const f = () => {}

πŸ¦„ ν™”μ‚΄ν‘œ ν•¨μˆ˜μ™€ ν‘œν˜„μ‹ 문​

  • ν™”μ‚΄ν‘œ ν•¨μˆ˜μ˜ λͺΈν†΅μ€ function λ•Œμ™€λŠ” λ‹€λ₯΄κ²Œ λ‹€μŒμ²˜λŸΌ μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•  μˆ˜λ„ 있고 μƒλž΅ν•  μˆ˜λ„ μžˆλ‹€.
const arrow1 = (a: number, b: number): number => { return a + b }
const arrow2 = (a: number, b: number): number => a + b;
  • μ€‘κ΄„ν˜Έ μ‚¬μš© 여뢀에 따라 νƒ€μž…μŠ€ν¬λ¦½νŠΈ 문법이 λ™μž‘ν•˜λŠ” 방식이 μ‹€ν–‰λ¬Έ(execution statement) 방식과 ν‘œν˜„μ‹ λ¬Έ(expression statement) λ°©μ‹μœΌλ‘œ 달라진닀.

πŸ“š μ‹€ν–‰λ¬Έκ³Ό ν‘œν˜„μ‹ 문​

  • λ‹€μŒμ²˜λŸΌ λ³€μˆ˜μ— 값을 λŒ€μž…ν•˜λŠ” 것은 λŒ€ν‘œμ μΈ 싀행문이닀.
let x
x = 1
  • λ°˜λ©΄μ— λ‹€μŒκ³Ό 같은 μ½”λ“œμ—μ„œ x > 10 뢀뢄은 CPUκ°€ ν‰κ°€ν•œ ν›„ trueλ‚˜ falseλΌλŠ” κ°’μœΌλ‘œ κ²°κ³Όλ₯Ό μ•Œλ €μ£Όμ§€ μ•ŠμœΌλ©΄ if문이 μ •μƒμ μœΌλ‘œ λ™μž‘ν•  수 μ—†λ‹€.
let x = 10
if(x > 0)
x = 1
  • 그런데 만일 ν”„λ‘œκ·Έλž˜λ° 문법이 λ‹€μŒκ³Ό κ°™λ‹€λ©΄ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κΈ°κ²Œ λ²ˆκ±°λ‘œμ›Œμ§„λ‹€.
if(return x > 0)
x = 1
  • 즉, λ˜‘κ°™μ΄ CPUμ—μ„œ μ‹€ν–‰λ˜λŠ” ꡬ문이더라도 x > 0처럼 return ν‚€μ›Œλ“œ 없이 결괏값을 λ°˜ν™˜ν•˜λŠ” 싀행문이 ν•„μš”ν•˜λ‹€. 이λ₯Ό ν‘œν˜„μ‹ 문이라고 κ΅¬λΆ„ν•΄μ„œ λΆ€λ₯Έλ‹€.

πŸ“š 볡합 싀행문​

  • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ if와 같은 ꡬ문은 λ‹€μŒμ²˜λŸΌ 쑰건을 λ§Œμ‘±ν•˜λ©΄ λ‹¨μˆœνžˆ ν•œ μ€„μ˜ μ‹€ν–‰λ¬Έλ§Œμ„ μ‹€ν–‰ν•˜λŠ” ν˜•νƒœλ‘œ μ„€κ³„ν•œλ‹€.
if(쑰건식)
μ‹€ν–‰λ¬Έ
  • 이런 섀계가 κ°€λŠ₯ν•œ μ΄μœ λŠ” 볡합 μ‹€ν–‰λ¬Έμ΄λΌλŠ” 또 λ‹€λ₯Έ ν˜•νƒœλ₯Ό ν•¨κ»˜ μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
if(쑰건식) {
μ‹€ν–‰λ¬Έ1
μ‹€ν–‰λ¬Έ2
}
  • 볡합 싀행문은 컴파일러둜 ν•˜μ—¬κΈˆ μ—¬λŸ¬ 싀행문을 ν•œ 개처럼 μΈμ‹ν•˜κ²Œ ν•œλ‹€. λ”°λΌμ„œ μ»΄νŒŒμΌλŸ¬λŠ” μ•žμ˜ ν˜•νƒœλ‘œ μž‘μ„±λœ if문은 μ—¬μ „νžˆ ν•œ μ€„μ˜ μ‹€ν–‰λ¬ΈμœΌλ‘œ μΈμ‹ν•œλ‹€.

πŸ“š ν•¨μˆ˜ λͺΈν†΅κ³Ό 볡합 싀행문​

  • function ν‚€μ›Œλ“œλ‘œ λ§Œλ“œλŠ” ν•¨μˆ˜λŠ” λ°˜λ“œμ‹œ λͺΈν†΅μ„ μ€‘κ΄„ν˜Έλ‘œ 감싸야 ν•˜λŠ”λ°, μ—¬κΈ°μ„œ μ€‘κ΄„ν˜ΈλŠ” μ•žμ„œ μ„€λͺ…ν•œ 볡합 싀행문을 μ˜λ―Έν•œλ‹€.
  • λ”°λΌμ„œ ν•¨μˆ˜ λͺΈν†΅μ€ λ‹€μŒμ²˜λŸΌ μ—¬λŸ¬ μ€‘γ„Ήλ‘œ κ΅¬ν˜„ν•  수 μžˆλ‹€.
function f() {
let x = 1, y = 2;
let result = x + y + 10;
}

πŸ“š return ν‚€μ›Œλ“œβ€‹

  • 싀행문은 CPUμ—μ„œ μ‹€ν–‰λœ κ²°κ³Όλ₯Ό μ•Œλ €μ£Όμ§€ μ•ŠλŠ”λ‹€.
  • 예λ₯Ό λ“€μ–΄, ν•¨μˆ˜ λͺΈν†΅μ„ 볡합 μ‹€ν–‰λ¬ΈμœΌλ‘œ κ΅¬ν˜„ν•œ λ‹€μŒ ν•¨μˆ˜λŠ” trueλ‚˜ falseλ₯Ό λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€.
function isGreater(a: number, b: number): boolean {
a > b; // κ²°κ³Ό λ°˜ν™˜ x
}
  • μ‹€ν–‰λ¬Έ 기반 μ–Έμ–΄λŠ” 이 문제λ₯Ό ν•΄κ²°ν•˜λ €κ³  returnμ΄λΌλŠ” ν‚€μ›Œλ“œ λ„μž…ν–ˆλ‹€.
function isGreater(a: number, b: number): boolean {
return a > b; // true or false
}

πŸ“š ν‘œν˜„μ‹ λ¬Έ μŠ€νƒ€μΌμ˜ ν™”μ‚΄ν‘œ ν•¨μˆ˜ κ΅¬ν˜„β€‹

  • λ‹€μŒ function μŠ€νƒ€μΌ ν•¨μˆ˜ isGreaterλ₯Ό ν˜Έμ‚΄ν‘œ ν•¨μˆ˜λ‘œ κ΅¬ν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.
const isGreater = (a: number, b: number): boolean => {
return a > b;
}
  • return을 μƒλž΅ν•˜κ³  λ‹€μŒμ²˜λŸΌ κ΅¬ν˜„ν•  μˆ˜λ„ μžˆλ‹€.
const isGreater = (a: number, b: number): boolean => a > b;

πŸ“š ν‘œν˜„μ‹κ³Ό ν‘œν˜„μ‹ 문의 차이​

  • λ‹€μŒ μ½”λ“œμ—μ„œ 2행에 μžˆλŠ” a > b μ½”λ“œλŠ” Cμ–Έμ–΄μ—μ„œ ν‘œν˜„μ‹μ΄λΌκ³  ν–ˆκΈ° λ•Œλ¬Έμ— κ·Έ 이후에 λ§Œλ“€μ–΄μ§„ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ“€λ‘œ 같은 의미둜 ν‘œν˜„μ‹μ΄λΌκ³  μƒκ°ν•œλ‹€.
  • λ°˜λ©΄μ— ν‘œν˜„μ‹ 지ν–₯ μ–Έμ–΄ κ΄€μ μ—μ„œ 3ν–‰μ˜ a > b μ½”λ“œλŠ” κ·Έ μžμ²΄κ°€ 싀행문이닀.
let a = 1, b = 0;
if(a > b) console.log('a is greater than b');
const isGreater = (a: number, b: number): boolean => a > b;
  • 이 λ‘˜μ„ κ΅¬λΆ„ν•˜κ³ μž ν‘œν˜„μ‹κ³Ό ν‘œν˜„μ‹ 문으둜 κ΅¬λΆ„ν•œ 것이닀.

πŸ¦„ 일등 ν•¨μˆ˜ μ‚΄νŽ΄λ³΄κΈ°β€‹

πŸ“š 콜백 ν•¨μˆ˜β€‹

  • 일등 ν•¨μˆ˜(first-class-function) κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λŠ” ν•¨μˆ˜ ν‘œν˜„μ‹μ΄λΌλŠ” μΌμ’…μ˜ 값이닀. λ”°λΌμ„œ λ³€μˆ˜μ— 담을 수 μžˆλ‹€.
  • 이 말은 ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ§€κ°œλ³€μˆ˜λ‘œ 받을 수 μžˆλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.
  • 이처럼 λ§€κ°œλ³€μˆ˜ ν˜•νƒœλ‘œ λ™μž‘ν•˜λŠ” ν•¨μˆ˜λ₯Ό 콜백 ν•¨μˆ˜λΌκ³  ν•œλ‹€.
  • λ‹€μŒ μ½”λ“œλŠ” 콜백 ν•¨μˆ˜ μ‚¬μš© μ˜ˆμ΄λ‹€.
// init.ts
export const init = (callback: () => void): void => {
console.log('default initialization finished.');
callback();
console.log('all initialization finished.');
}

// callback.ts
import { init } from "./init";

init(() => console.log('custom initialization finished.'));

// default initialization finished.
// custom initialization finished.
// all initialization finished.

πŸ“š μ€‘μ²©ν•¨μˆ˜β€‹

  • ν•¨μˆ˜ν˜• μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λŠ” λ³€μˆ˜μ— λ‹΄κΈ΄ ν•¨μˆ˜ ν‘œν˜„μ‹μ΄λ―€λ‘œ ν•¨μˆ˜ μ•ˆμ— 또 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ€‘μ²©ν•΄μ„œ κ΅¬ν˜„ν•  수 μžˆλ‹€.
const calc = (value: number, cb: (number) => void): void => {
let add = (a, b) => a + b;
function multiply(a, b) {
return a * b;
}

let result = multiply(add(1, 2), value);
cb(result);
}

calc(30, (result: number) => console.log(`result is ${result}`));
// result is 90

πŸ“š κ³ μ°¨ ν•¨μˆ˜μ™€ ν΄λ‘œμ €, 그리고 λΆ€λΆ„ ν•¨μˆ˜β€‹

  • κ³ μ°¨ ν•¨μˆ˜(high-order function)λŠ” 또 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§ν•œλ‹€.
  • ν•¨μˆ˜ν˜• μ–Έμ–΄μ—μ„œ ν•¨μˆ˜λŠ” λ‹¨μˆœνžˆ ν•¨μˆ˜ ν‘œν˜„μ‹μ΄λΌλŠ” κ°’μ΄λ―€λ‘œ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.
  • λ‹€μŒμ€ κ³ μ°¨ ν•¨μˆ˜μ˜ μ˜ˆμ΄λ‹€.
const add = (a: number): (number) => number => (b: number): number => a + b;
const result = add(1)(2);
console.log(result); // 3
  • μœ„ ꡬ문을 더 μ΄ν•΄ν•˜κΈ° μ‰¬μš΄ ν˜•νƒœλ‘œ λ‹€μ‹œ κ΅¬ν˜„ν•œ 것이닀.
  • λ‹€μŒ μ½”λ“œλŠ” number νƒ€μž…μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„ number νƒ€μž…μ˜ 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό NumberToNumberFunc νƒ€μž…μœΌλ‘œ μ •μ˜ν•œλ‹€.
type NumberToNumberFunc = (number) => number
  • 이제 NumberToNumberFunc νƒ€μž…μ˜ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” add와 같은 ν•¨μˆ˜λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.
export const add = (a: number): NumberToNumberFunc => {
// NumberToNumberFunc νƒ€μž…μ˜ ν•¨μˆ˜ λ°˜ν™˜
}
  • λ‹€μŒμœΌλ‘œ add의 λ°˜ν™˜κ°’μ„ 쀑첩 ν•¨μˆ˜λ‘œ κ΅¬ν˜„ν•  수 μžˆλ‹€.
  • _add의 λͺΈν†΅μ„ κ΅¬ν˜„ν•˜λ©΄ λ‹€μŒμ²˜λŸΌ addλΌλŠ” μ΄λ¦„μ˜ κ³ μ°¨ ν•¨μˆ˜κ°€ μ™„μ„±λœλ‹€.
export type NumberToNumberFunc = (number) => number
export const add = (a: number): NumberToNumberFunc => {
const _add: NumberToNumberFunc = (b: number): number => {
return a + b; // ν΄λ‘œμ €
}
return _add;
}
  • aλŠ” _add ν•¨μˆ˜μ˜ κ΄€μ μ—μ„œλ§Œ 보면 μ™ΈλΆ€μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ΄λ‹€.
  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œλŠ” λ‹€μŒκ³Ό 같은 ν˜•νƒœλ₯Ό ν΄λ‘œμ €(closure) 라고 ν•œλ‹€.
  • NumberToNumberFunc νƒ€μž…μ˜ 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ―€λ‘œ λ‹€μŒκ³Ό 같은 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.
let fn1: NumberToNumberFunc = add(1);
let result = fn1(2);
console.log(result); // 3

console.log(add(1)(2)); // 3
  • μœ„μ™€ 같이 2μ°¨ κ³ μ°¨ν•¨μˆ˜μΈ addλŠ” add(1)(2) 처럼 ν•¨μˆ˜ 호좜 μ—°γ„΄μ‚°μžλ₯Ό 두 개 μ‚¬μš©ν•΄μ•Όλ§Œ ν•¨μˆ˜κ°€ μ•„λ‹Œ 값을 얻을 수 μžˆλ‹€.
const multiply = a => b => c => a * b * c;
  • λ§Œμ•½ 3μ°¨ κ³ μ°¨ν•¨μˆ˜μΈ κ²½μš°μ— 두 개만 뢙이면 아직 값이 μ•„λ‹Œ ν•¨μˆ˜μ΄λ‹€.
  • 이것을 λΆ€λΆ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν˜Ήμ€ λΆ€λΆ„ 적용 ν•¨μˆ˜(partially applied function)라고 ν•œλ‹€.

πŸ¦„ ν•¨μˆ˜ κ΅¬ν˜„ 기법​

πŸ“š λ§€κ°œλ³€μˆ˜ κΈ°λ³Έκ°’ μ§€μ •ν•˜κΈ°β€‹

  • 선택적 λ§€κ°œλ³€μˆ˜λŠ” 항상 κ·Έ 값이 undefined둜 κ³ μ •λœλ‹€.
  • 만일, ν•¨μˆ˜ 호좜 μ‹œ 인수λ₯Ό μ „λ‹¬ν•˜μ§€ μ•Šλ”λΌλ„ λ§€κ°œλ³€μˆ˜μ— μ–΄λ–€ 값을 μ„€μ •ν•˜κ³  μ‹Άλ‹€λ©΄ λ§€κ°œλ³€μˆ˜μ˜ 기본값을 지정할 수 μžˆλ‹€.
  • 이λ₯Ό λ””ν΄νŠΈ λ§€κ°œλ³€μˆ˜λΌκ³  ν•œλ‹€.
export type Person = {
name: string, age: number
}

export const makePerson = (name: string, age: number = 10): Person => {
const person = { name, age }; // 단좕 ꡬ문
return person;
}

console.log(makePerson('Jack')); // { name: 'Jack', age: 10 }

πŸ“š 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ λ§Œλ“€κΈ°β€‹

  • μ»΄νŒŒμΌλŸ¬κ°€ {}λ₯Ό 객체둜 ν•΄μ„ν•˜κ²Œ ν•˜λ €λ©΄ λ‹€μŒμ²˜λŸΌ 객체λ₯Ό μ†Œκ΄„ν˜Έλ‘œ 감싸주어야 ν•œλ‹€.
export const makePerson = (name: string, age: number = 10): Person => ({ name, age });

πŸ“š λ§€κ°œλ³€μˆ˜μ— 비ꡬ쑰화 ν• λ‹Ήλ¬Έ μ‚¬μš©ν•˜κΈ°β€‹

  • ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ„ λ³€μˆ˜μ˜ μΌμ’…μ΄λ―€λ‘œ λ‹€μŒμ²˜λŸΌ 비ꡬ쑰화 할당문을 μ μš©ν•  수 μžˆλ‹€.
export type Person = {
name: string, age: number
}

export const makePerson = ({name, age}: Person): void =>
console.log(`name: ${name}, age: ${age}`);

console.log(makePerson({ name: 'Jack', age: 10} )); // { name: 'Jack', age: 10 }

πŸ“š 색인 킀와 κ°’μœΌλ‘œ 객체 λ§Œλ“€κΈ°β€‹

const makeObject = (key, value) => ({ [key]: value });
console.log(makeObject('name', 'Jack')); // { name: 'Jack' }
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” { [key]: value } ν˜•νƒœμ˜ νƒ€μž…μ„ 색인 κ°€λŠ₯ νƒ€μž…μ΄λΌκ³  ν•˜λ©°, λ‹€μŒκ³Ό 같은 ν˜•νƒœλ‘œ key와 value의 νƒ€μž…μ„ λͺ…μ‹œν•œλ‹€.
export type KeyValueType = {
[key: string]: string
}

export const makeObject = (key: string, value: string): KeyValueType => ({
[key]: value,
});

console.log(makeObject('name','Jack')); // { name: 'Jack' }

πŸ¦„ 클래슀 λ©”μ„œλ“œβ€‹

πŸ“š function ν•¨μˆ˜μ™€ this ν‚€μ›Œλ“œβ€‹

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ function ν‚€μ›Œλ“œλ‘œ λ§Œλ“  ν•¨μˆ˜λŠ” Functionμ΄λž€ 클래슀의 μΈμŠ€ν„΄μŠ€, 즉 ν•¨μˆ˜λŠ” 객체라고 ν–ˆλ‹€.
  • 객체지ν–₯ μ–Έμ–΄μ—μ„œ μΈμŠ€ν„΄μŠ€λŠ” this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” function ν‚€μ›Œλ“œλ‘œ λ§Œλ“  ν•¨μˆ˜μ— this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
  • λ°˜λ©΄μ— ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—λŠ” this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.

πŸ“š λ©”μ„œλ“œλž€?​

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ λ©”μ„œλ“œλŠ” function으둜 λ§Œλ“  ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ‹΄κ³  μžˆλŠ” 속성이닀.
  • λ‹€μŒ μ½”λ“œμ—μ„œ 클래슀 AλŠ” value와 methodλΌλŠ” 두 개의 속성을 가진닀.
export class A {
value: number = 1;
method: () => void = function(): void {
console.log(`value: ${this.value}`);
}
}
  • value 속성을 1둜 μ„€μ •ν–ˆμœΌλ―€λ‘œ this.valueκ°€ 1이 λ˜μ–΄ value: 1μ΄λΌλŠ” λ¬Έμžμ—΄μ΄ 좜λ ₯λœλ‹€.
import { A } from "./A";

let a: A = new A;
a.method(); // value: 1

πŸ“š 클래슀 λ©”μ„œλ“œ ꡬ문​

  • μ•žμ—μ„œ μž‘μ„±ν•œ 클래슀 AλŠ” κ΅¬ν˜„ν•˜κΈ°λ„ 번거둭고 가독성도 떨어진닀.
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 클래슀 속성 쀑 ν•¨μˆ˜ ν‘œν˜„μ‹μ„ λ‹΄λŠ” 속성은 function ν‚€μ›Œλ“œλ₯Ό μƒλž΅ν•  수 있게 ν•˜λŠ” 단좕 ꡬ문을 μ œκ³΅ν•œλ‹€.
export class B {
constructor(public value: number = 1) {}
method(): void {
console.log(`value: ${this.value}`);
}
}
  • B 클래슀의 μƒμ„±μžλ₯Ό 톡해 μ „λ‹¬λœ 2λΌλŠ” 값이 value에 μ„€μ •λ˜κ³  methodκ°€ ν˜ΈμΆœλ˜μ–΄ 2λΌλŠ” 값이 좜λ ₯λœλ‹€.
import { B } from "./B";

let b: B = new B(2);
b.method(); // value: 2

πŸ“š 정적 λ©”μ„œλ“œβ€‹

  • 클래슀의 속성은 static μˆ˜μ •μžλ₯Ό 속성 μ•žμ— λΆ™μ—¬μ„œ μ •μ μœΌλ‘œ λ§Œλ“€ 수 μžˆμ—ˆλ‹€.
  • λ©”μ„œλ“œ λ˜ν•œ μ†μ„±μ΄λ―€λ‘œ 이름 μ•žμ— static μˆ˜μ •μžλ₯Ό λΆ™μ—¬ 정적 λ©”μ„œλ“œλ₯Ό λ§Œλ“€ 수 μžˆμ—ˆλ‹€.
  • λ‹€μŒ μ½”λ“œλŠ” C와 DλΌλŠ” 두 ν΄λž˜μŠ€κ°€ whoAreYouλΌλŠ” 같은 μ΄λ¦„μ˜ 정적 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜κ³  μžˆλ‹€.
export class C {
static whoAreYou(): string {
return `I'm class C`;
}
}

export class D {
static whoAreYou(): string {
return `I'm class D`;
}
}

console.log(C.whoAreYou()); // I'm class C
console.log(D.whoAreYou()); // I'm class D

πŸ“š λ©”μ„œλ“œ 체인​

  • 객체의 λ©”μ„œλ“œλ₯Ό μ΄μ–΄μ„œ 계속 ν˜ΈμΆœν•˜λŠ” λ°©μ‹μ˜ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλŠ”λ° μ΄λŸ¬ν•œ 방식을 λ©”μ„œλ“œ 체인이라고 ν•œλ‹€.
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλ‘œ λ©”μ„œλ“œ 체인을 κ΅¬ν˜„ν•˜λ €λ©΄ λ©”μ„œλ“œκ°€ 항상 thisλ₯Ό λ°˜ν™˜ν•˜κ²Œ ν•œλ‹€.
export class calculator {
constructor(public value: number = 0) {}

add(value: number) {
this.value += value;
return this;
}

multiply(value: number) {
this.value *= value;
return this;
}
}
  • λ‹€μŒκ³Ό 같이 κ΅¬ν˜„ν•  수 μžˆλ‹€.
import { Calculator } from "./method-chain";

let calc = new Calculator;
let result = calc.add(1).add(2).multiply(3).multiply(4).value;
console.log(result); // 36