🦁_21.12.02 TIL

BoriΒ·2021λ…„ 12μ›” 2일
3
post-thumbnail

21λ…„ 12μ›” 02일

πŸ“ Javascript

πŸ“Ž μž¬κ·€ ν•¨μˆ˜(Recursive function)

  • 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜
  • μžμ‹ μ„ λ¬΄ν•œνžˆ 연쇄 ν˜ΈμΆœν•  수 μžˆλ‹€.
    • ν˜ΈμΆœμ„ 멈좜 수 μžˆλŠ” νƒˆμΆœ 쑰건이 λ°˜λ“œμ‹œ ν•„μš”
      => νƒˆμΆœ 쑰건이 μ—†λŠ” 경우, λ¬΄ν•œ λ°˜λ³΅μ— λΉ μ Έ stackoverflow μ—λŸ¬λ₯Ό λ°œμƒ
// νŒ©ν† λ¦¬μ–Ό
// n! = 1 * 2 * 3 * ... * n
function factorial(n) {
  if (n <= 1) {
    return n;
  }
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

// μ‹œκ·Έλ§ˆ
function sigma(n) {
  if (n <= 1) {
    return n;
  }
  return n + sigma(n - 1);
}

console.log(sigma(5)); // 15

// ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄
// ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ€ 0κ³Ό 1둜 μ‹œμž‘, λ‹€μŒ ν”Όλ³΄λ‚˜μΉ˜ μˆ˜λŠ” λ°”λ‘œ μ•žμ˜ 두 ν”Όλ³΄λ‚˜μΉ˜ 수의 합이 λœλ‹€.
// 0, 1, 1, 2, 3, 5, 8, 13, ...
function fibonacci(n) {
 if (n < 2) {
   return n; 
 }
  return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(0)); // 0
console.log(fibonacci(1)); // 1
console.log(fibonacci(2)); // 1 = fibonacci(1) + fibonacci(0)
console.log(fibonacci(3)); // 2 = fibonacci(2) + fibonacci(1)
console.log(fibonacci(4)); // 3 = fibonacci(3) + fibonacci(2)

μž¬κ·€ ν•¨μˆ˜λŠ” stackμ΄λΌλŠ” λ©”λͺ¨λ¦¬ 곡간 μ‚¬μš©

  • 반볡적으둜 stack λ©”λͺ¨λ¦¬ 곡간을 μ΄μš©ν•˜κΈ° λ•Œλ¬Έμ— μ„±λŠ₯이 쒋지 μ•Šλ‹€.
  • ν˜ΈμΆœλ˜λŠ” 것이 λ©”λͺ¨λ¦¬λ₯Ό μ°¨μ§€ν•˜κ³  μžˆμœΌλ―€λ‘œ 반볡문, λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°(λ©”λͺ¨μ΄μ œμ΄μ…˜(ν•˜ν–₯식), νƒ€λ·Έλ ˆμ΄μ…˜(상ν–₯식))을 적절히 λ―Ήμ‹±ν•΄μ„œ μ‚¬μš©
    • λ©”λͺ¨μ΄μ œμ΄μ…˜(Memoization) : ν•œ 번 κ³„μ‚°ν•œ κ²°κ³Όλ₯Ό μΊμ‹œμ— λ©”λͺ¨(μ €μž₯)ν•˜λŠ” 것
      => λ°˜λ³΅λ˜λŠ” κ²°κ³Όλ₯Ό λ©”λͺ¨λ¦¬μ— μ €μž₯ν•΄μ„œ 또 λ‹€λ₯Έ κ²°κ³Όλ₯Ό 계산할 λ•Œ 빨리 싀행될 수 μžˆλ„λ‘ ν•œλ‹€.
// λ©”λͺ¨μ΄μ œμ΄μ…˜
let fibo_cache = [];
function fibo(n) {
 if (n in fibo_cache) {
   return fibo_cache[n];
 }
  fibo_cache[n] = n < 2 ? n : fibo(n - 2) + fibo(n - 1);
  return fibo_cache[n];
}

πŸ“Ž μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜(IIFE, Immediately Invoke Function Expression)

  • ν•¨μˆ˜μ˜ μ •μ˜μ™€ λ™μ‹œμ— μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜
  • 졜초 ν•œ 번만 호좜되며 λ‹€μ‹œ ν˜ΈμΆœν•  수 μ—†λ‹€.
  • μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유?
    • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 파일이 λΆ„λ¦¬λ˜μ–΄ μžˆμ–΄λ„ κΈ€λ‘œλ²Œ μŠ€μ½”ν”„κ°€ ν•˜λ‚˜μ΄κ³ , κΈ€λ‘œλ²Œ μŠ€μ½”ν”„μ— μ„ μ–Έλœ λ³€μˆ˜λ‚˜ ν•¨μˆ˜λŠ” μ½”λ“œ λ‚΄ μ–΄λ””μ„œλ“ μ§€ μ ‘κ·Ό κ°€λŠ₯
      => λ‹€λ₯Έ 슀크립트 파일 내에 λ™μΌν•œ μ΄λ¦„μœΌλ‘œ λͺ…λͺ…λœ λ³€μˆ˜λ‚˜ ν•¨μˆ˜κ°€ 같은 μŠ€μ½”ν”„ 내에 μ‘΄μž¬ν•  경우 μ˜λ„ν•˜μ§€ μ•Šμ€ κ²°κ³Όκ°€ λ‚˜νƒ€λ‚  수 μžˆλ‹€.
      => λ³€μˆ˜λ₯Ό κΈ€λ‘œλ²Œ μŠ€μ½”ν”„λ‘œ μ„ μ–Έν•˜λŠ” 것을 ν”Όν•˜κΈ° μœ„ν•΄ ν•œ 번의 μ‹€ν–‰λ§Œ ν•„μš”λ‘œ ν•˜λŠ” μ΄ˆκΈ°ν™” μ½”λ“œμ— 많이 μ‚¬μš©
    • ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό κ°€μ§€λ―€λ‘œ μ•ˆμ— μžˆλŠ” λ³€μˆ˜λ“€μ΄ νœ˜λ°œλ˜λ©΄μ„œ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½
// κΈ°λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜
(function myFunc() {
  var a = 3;
  var b = 5;
  return a + b;
}());

// 읡λͺ… μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜
(function () {
  var a = 3;
  var b = 5;
  return a + b;
}());

// ν•¨μˆ˜ 선언문은 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ ν•¨μˆ˜ λͺΈμ²΄λ₯Ό λ‹«λŠ” μ€‘κ΄„ν˜Έ 뒀에 μ„Έλ―Έμ½œλ‘ (;)이 μžλ™μœΌλ‘œ μΆ”κ°€λœλ‹€.
function () {
  ...
}(); // };(); μ΄λ ‡κ²Œ
  
// λ”°λΌμ„œ μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λŠ” 전체λ₯Ό μ†Œκ΄„ν˜Έλ‘œ 감싸쀀닀.
(function () {
  ...
}());

참고 링크

πŸ“Ž Call-by-value

  • ν•¨μˆ˜ 호좜 μ‹œ 인수λ₯Ό ν•¨μˆ˜μ— λ§€κ°œλ³€μˆ˜λ‘œ 전달할 λ•Œ, λ§€κ°œλ³€μˆ˜μ— 원본 값이 μ•„λ‹Œ λ³΅μ‚¬λœ 값을 ν•¨μˆ˜λ‘œ 전달
  • λ”°λΌμ„œ, ν•¨μˆ˜ λ‚΄μ—μ„œ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 κ°’(=λ³΅μ‚¬λœ κ°’)이 λ³€κ²½λ˜μ–΄λ„ 원본 값은 λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€.
function change(parameter) {
  console.log(Object.is(parameter, num)); // true => parameter와 num이 같은 값을 가리킀고 μžˆλ‹€.

  parameter += 10;
  // parameter의 값이 λ°”λ€Œλ©΄ parameter와 num의 λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ 달라진닀
  console.log(Object.is(parameter, num)); // false => parameter != num

  return parameter;
}

let num = 0;
// changeν•¨μˆ˜μ— num을 전달,
console.log(change(num)); // 10 이 λ°˜ν™˜λ¨

// 원본 값인 num이 changeν•¨μˆ˜μ— μ˜ν•΄ λ°”κΌˆλŠ”μ§€ 확인
console.log(num); // 0 => μ¨”μž” μ•ˆλ°”λ€œ! 원본값은 μ•ˆ λ°”λ€œ!

πŸ“Ž Call-by-reference

  • ν•¨μˆ˜ 호좜 μ‹œ κ°μ²΄ν˜• 인수λ₯Ό ν•¨μˆ˜μ— λ§€κ°œλ³€μˆ˜λ‘œ 전달할 λ•Œ, λ§€κ°œλ³€μˆ˜μ— 값이 λ³΅μ‚¬λ˜μ§€ μ•Šκ³  객체의 참쑰값이 λ§€κ°œλ³€μˆ˜λ‘œ μ €μž₯λ˜μ–΄ ν•¨μˆ˜λ‘œ 전달
  • ν•¨μˆ˜ λ‚΄μ—μ„œ λ§€κ°œλ³€μˆ˜μ˜ 참쑰값을 μ΄μš©ν•˜μ—¬ 객체의 값을 λ³€κ²½ν–ˆμ„ λ•Œ μ „λ‹¬λ˜μ–΄μ§„ κ°μ²΄ν˜• μΈμˆ˜κ°’λ„ 같이 λ³€κ²½
function changeObj(primitive, object) {
  console.log(Object.is(primitive, prm_num)); // true
  console.log(Object.is(object, obj)); // true => 같은 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό 가리킴

  console.log(prm_num); // 0
  console.log(obj); // { name: 'Name', age: 'Age' }

  primitive += 10;

  object.name = "Changed Name";
  object.age = "Changed Age";

  console.log(Object.is(primitive, prm_num)); // false => call by value μ°Έκ³ 
  console.log(Object.is(object, obj)); // true => μ—¬μ „νžˆ 같은 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό 가리킴

  console.log(primitive); // 10
  console.log(prm_num); // 0 => 원본 κ°’ λ°”λ€Œμ§€ μ•ŠμŒ
  console.log(obj); // { name: 'Changed Name', age: 'Changed Age' } => 원본 데이터 λ°”λ€œ
}

let prm_num = 0;
let obj = {
  name: "Name",
  age: "Age",
};

changeObj(prm_num, obj);

console.log(prm_num); // 0
console.log(obj); // { name: 'Changed Name', age: 'Changed Age' }

πŸ“Ž Call-by-sharing

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” call by value만 쑴재
  • κ°μ²΄ν˜•μ„ 인자둜 ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λ©΄ 원본 μ£Όμ†Œ 값이 μ•„λ‹ˆλΌ μ£Όμ†Œ κ°’μ˜ 볡사본이 λ„˜μ–΄κ°„λ‹€.
  • μ˜ˆμ™Έλ‘œ κ°μ²΄ν˜•μ€ index둜 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό 따라 값을 μ²˜λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— call by reference둜 λ™μž‘ν•˜λŠ” κ²ƒμ²˜λŸΌ λ™μž‘ν•œλ‹€.
// call by sharing μ˜ˆμ‹œ 1
function changeEmptyObj(obj) {
  obj = { item1: "Changed item1" }; //  obj μ£Όμ†Œ μž¬ν• λ‹Ή
  obj.item2 = "Changed item2"; // μ£Όμ†Œ μž¬ν• λ‹Ή 된 obj의 item2 λ³€κ²½

  console.log(obj); // { item1: 'Changed item1', item2: 'Changed item2' } => μ£Όμ†Œ μž¬ν• λ‹Ή 된 obj
}

let originalObj = { item1: "item1", item2: "item2" };

changeEmptyObj(originalObj);
console.log(originalObj); // { item1: 'item1', item2: 'item2' } => 원본 λ°μ΄ν„°λŠ” λ³€ν•˜μ§€ μ•ŠμŒ
  • μž¬λ―ΈμžˆλŠ” μ˜ˆμ‹œ
// call by sharing μ˜ˆμ‹œ 2
function changeEmptyObj(obj) {
  // μ˜ˆμ‹œ 1의 μ½”λ“œ μˆœμ„œλ₯Ό 변경함
  obj.item2 = "Changed item2"; // originalObj.item2 λ³€κ²½
  obj = { item1: "Changed item1" }; //  obj μ£Όμ†Œ μž¬ν• λ‹Ήν•˜λ©΄μ„œ originalObj와 달라짐, λ³΅μ‚¬λœ obj.item1의 값은 λ°”λ€Œκ³  item2λŠ” 없어짐

  console.log(obj); // { item1: 'Changed item1' } => item1만 남은 obj 좜λ ₯
}

let originalObj = { item1: "item1", item2: "item2" };

changeEmptyObj(originalObj);
console.log(originalObj); // { item1: 'item1', item2: 'Changed item2' } => changeEmptyObj에 μ˜ν•΄ item2λŠ” 변경됨

πŸ“Ž map

  • map은 λ°°μ—΄ μš”μ†Œ 전체λ₯Ό λŒ€μƒμœΌλ‘œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , ν•¨μˆ˜ 호좜 κ²°κ³Όλ₯Ό λ°°μ—΄λ‘œ λ°˜ν™˜
let result = arr.map(function(item, index, array) {
  // μš”μ†Œ λŒ€μ‹  μƒˆλ‘œμš΄ 값을 λ°˜ν™˜
});
let array = [1, 4, 9, 16];
let κ°’1 = array.map((x) => x * 2);

console.log(array); // [ 1, 4, 9, 16 ]
console.log(κ°’1); // [ 2, 8, 18, 32 ]

function 제곱(x) {
  return x ** 2;
}

κ°’2 = array.map(제곱);
console.log(κ°’2); // [ 1, 16, 81, 256 ]

// sqrt = square root
console.log(array.map(Math.sqrt).map((x) => x ** 3)); // [ 1, 8, 27, 64 ]

πŸ“Ž filter

  • filterλŠ” true값인 κ²ƒλ§Œ λ°˜ν™˜
const words = [
  "spray",
  "limit",
  "elite",
  "exuberant",
  "destruction",
  "present",
];

// word.length > 6κ°€ true κ°’λ§Œ λ°˜ν™˜
const result = words.filter((word) => word.length > 6);

console.log(result); // [ 'exuberant', 'destruction', 'present' ]

πŸ“Ž Map

  • 객체 : ν‚€κ°€ μžˆλŠ” μ»¬λ ‰μ…˜μ„ μ €μž₯
  • 맡(Map) : 킀와 κ°’μ˜ 쌍으둜 이루어진 μ»¬λ ‰μ…˜.
    => 객체와 μœ μ‚¬ν•˜μ§€λ§Œ 차이점이 μžˆλ‹€.
ꡬ뢄객체Map
ν‚€λ‘œ μ‚¬μš©ν•  수 μžˆλŠ” κ°’λ¬Έμžμ—΄, μ‹¬λ²Œκ°’κ°μ²΄λ₯Ό ν¬ν•¨ν•œ λͺ¨λ“  κ°’
μ΄ν„°λŸ¬λΈ”βŒβ­•
μš”μ†Œ 개수 확인 방법Object.key(obj).lengthmap.size
  • μ£Όμš” λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°
    • new Map() : μƒμ„±μž ν•¨μˆ˜λ‘œ 맡 생성
    • map.set(key, value) : 맡에 κ°’ λ„£κΈ°. keyλ₯Ό μ΄μš©ν•΄ valueλ₯Ό μ €μž₯
    • map.get(key) : key에 ν•΄λ‹Ήν•˜λŠ” κ°’ λ°˜ν™˜. keyκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ undefined λ°˜ν™˜
    • map.has(key) : keyκ°€ Map에 μ‘΄μž¬ν•˜λ©΄ true, μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ false λ°˜ν™˜
    • map.delete(key) : key에 ν•΄λ‹Ήν•˜λŠ” κ°’ μ‚­μ œ
    • map.clear() : 맡 μ•ˆμ˜ λͺ¨λ“  μš”μ†Œ 제거
    • map.size : 맡 μ•ˆμ˜ μš”μ†Œ 갯수 λ°˜ν™˜

맡의 μš”μ†Œμ— 반볡 μž‘μ—…ν•˜κΈ°

  • 맡 κ°μ²΄λŠ” μ΄ν„°λŸ¬λΈ”μ΄λ©΄μ„œ μ΄ν„°λ ˆμ΄ν„°μΈ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 제곡
    => for of문으둜 μˆœνšŒν•  수 μžˆλ‹€.

  • map.key() : 각 μš”μ†Œμ˜ ν‚€λ₯Ό λͺ¨μ€ 반볡 κ°€λŠ₯ν•œ(iterable) 객체λ₯Ό λ°˜ν™˜

  • map.values() : 각 μš”μ†Œμ˜ 값을 λͺ¨λ“  μ΄ν„°λŸ¬λΈ” 객체 λ°˜ν™˜

  • map.entries() : μš”μ†Œμ˜ [ν‚€, κ°’]을 ν•œ 쌍으둜 ν•˜λŠ” μ΄ν„°λŸ¬λΈ” 객체λ₯Ό λ°˜ν™˜

  • 맡은 μš”μ†Œμ˜ μˆœμ„œμ— 의미λ₯Ό 갖지 μ•Šμ§€λ§Œ 맡 객체λ₯Ό μˆœνšŒν•˜λŠ” μˆœμ„œλŠ” μš”μ†Œκ°€ μΆ”κ°€λœ μˆœμ„œλ₯Ό λ”°λ₯Έλ‹€.
    => ECMAScript 사양에 κ·œμ •λ˜μ–΄ μžˆμ§€ μ•Šμ§€λ§Œ λ‹€λ₯Έ μ΄ν„°λŸ¬λΈ”μ˜ μˆœνšŒμ™€ ν˜Έν™˜μ„±μ„ μœ μ§€ν•˜κΈ° μœ„ν•¨

πŸ“Ž Set

  • λ°°μ—΄ : μˆœμ„œκ°€ μžˆλŠ” μ»¬λ ‰μ…˜μ„ μ €μž₯

  • Set : μ€‘λ³΅λ˜μ§€ μ•ŠλŠ” μœ μΌν•œ κ°’λ“€μ˜ 집합.
    => λ°°μ—΄κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ 차이점이 μžˆλ‹€.

    • Set의 νŠΉμ„±μ€ μˆ˜ν•™μ  μ§‘ν•©μ˜ νŠΉμ„±κ³Ό 일치
      => Set은 μˆ˜ν•™μ  집합을 κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ 자료ꡬ쑰
      => Set을 톡해 ꡐ집합, 합집합, 차집합, 여집합 λ“± κ΅¬ν˜„ κ°€λŠ₯

      ꡬ뢄배열Set
      λ™μΌν•œ 값을 μ€‘λ³΅ν•˜μ—¬ 포함 κ°€λŠ₯β­•βŒ
      μš”μ†Œ μˆœμ„œμ— μ˜λ―Έβ­•βŒ
      인덱슀둜 μš”μ†Œμ— μ ‘κ·Όβ­•βŒ
  • μ£Όμš” λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°

    • new Set(iterable) : μƒμ„±μž ν•¨μˆ˜λ‘œ Set 생성
      => μ΄ν„°λŸ¬λΈ” 객체λ₯Ό μ „λ‹¬λ°›μœΌλ©΄ κ·Έ μ•ˆμ˜ 값을 λ³΅μ‚¬ν•΄μ„œ Set에 λ„£λŠ”λ‹€.
    • set.add(key, value) : 값을 μΆ”κ°€ν•˜κ³  Set μžμ‹ μ„ λ°˜ν™˜
    • set.has(key) : Set 내에 값이 μ‘΄μž¬ν•˜λ©΄ true, μ•„λ‹ˆλ©΄ false λ°˜ν™˜
    • set.delete(key) : 값을 제거. 호좜 μ‹œμ μ— Set 내에 값이 μžˆμ–΄μ„œ μ œκ±°μ— μ„±κ³΅ν•˜λ©΄ true, μ•„λ‹ˆλ©΄ false λ°˜ν™˜
    • set.clear() : Set의 λͺ¨λ“  μš”μ†Œ 일괄 μ‚­μ œ
    • set.size : Set μ•ˆμ˜ μš”μ†Œ 갯수 λ°˜ν™˜

마무리

  • Call-by-sharing이 λ‚˜λ₯Ό μ•„μ£Ό λ‚œκ°ν•˜κ²Œ λ§Œλ“€μ—ˆμ—ˆλŠ”λ° 도움을 λ°›κ³  마음이 νŽΈμ•ˆν•΄μ‘Œλ‹€.
  • 정리 μž˜ν•˜κ³  μ‹Άλ‹€μ•„μ•„ μ™œ ν•˜λ£¨λŠ” 24μ‹œκ°„μΈκ°€μ•„μ•„

2개의 λŒ“κΈ€

comment-user-thumbnail
2021λ…„ 12μ›” 5일

잘 보고 κ°‘λ‹ˆλ‹€ γ…Žγ…Žγ…Ž

λ‹΅κΈ€ 달기

μ—¬μœ½μ‹œ μš°λ¦¬λ½€λ¦¬λ‹˜!! γ…‹γ…‹

λ‹΅κΈ€ 달기