λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
λ…μ„œ

[ 독후감 ] ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ„ 읽고..

by YWTechIT 2023. 4. 27.
728x90

πŸ“ [ 독후감 ] ν•¨μˆ˜ν˜• μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό 읽고..

book-thumbnail

✏️ μ„œλ‘ 

이 책은 μž‘λ…„μ— 사내 ν”„λ‘œμ νŠΈλ₯Ό λ™λ£Œμ™€ νŽ˜μ–΄ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ©΄μ„œ μž‘λ‹΄μ‹œκ°„μ— ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄ 무엇인지 μ„€λͺ…ν•΄ μ£Όκ³  κ΄€λ ¨ μ„œμ μ„ μΆ”μ²œν•΄ μ€˜μ„œ 읽게 된 책이닀. (이후 사내 μŠ€ν„°λ”” 주제λ₯Ό ν•˜μŠ€μΌˆλ‘œ μ •ν•˜λ©΄μ„œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° κ³΅λΆ€μ˜ μ—°μž₯선이 λ˜μ—ˆλ‹€.)

 

λ…μ„œ 기간은 22.10.11.λΆ€ν„° 23.4.27.이며, 책은 μ•½ 320μͺ½μœΌλ‘œ κ΅¬μ„±λ˜μ–΄μžˆκ³ , ν•˜μŠ€μΌˆμ„ λ°°μš°λŠ” λŒ€μ‹  μ΅μˆ™ν•œ ꡬ문을 보며 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— μž…λ¬Έν•˜λ €λŠ” λ…μžμ—κ²Œ μ•ˆμ„±λ§žμΆ€μž…λ‹ˆλ‹€.(라고 μ„œλ‘μ— μ ν˜€μžˆμ§€λ§Œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° 자체의 λ‚œμ΄λ„λŠ” μ‰¬μš΄ νŽΈμ€ μ•„λ‹ˆλΌμ„œ μžλ°”μŠ€ν¬λ¦½νŠΈ 문법을 μ–΄λŠ 정도 μ•„λŠ” λΆ„λ“€μ—κ²Œ ꢌμž₯ν•˜κ³ ν”ˆ 책이닀.)

 

μ±…μ˜ λ‚΄μš©μ€ κ³ κ³„ν•¨μˆ˜, ν΄λ‘œμ €, ν•¨μˆ˜ 컀링/ν•©μ„± λ“±μ˜ κ°œλ…κ³Ό λžŒλ‹€ ν‘œν˜„μ‹, μ΄ν„°λ ˆμ΄ν„°, μ œλ„ˆλ ˆμ΄ν„°, ν”„λ‘œλ―ΈμŠ€ 같은 ES6 그리고 λͺ¨λ‚˜λ“œ, λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž˜λ°, 이벀트 쀑심 및 비동기 μ½”λ“œλ₯Ό ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ ν’€μ–΄λ‚Έ 책이닀.

 

λ˜ν•œ, 이 μ±…μ—μ„œ ν•¨μˆ˜ν˜•μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„± ν•  λ•Œ μ„œλ“œνŒŒν‹° 라이브러리(λ‘œλŒ€μ‹œJS, λžŒλ‹€JS, RxJS λ“±..)λ₯Ό μ‚¬μš©ν–ˆλŠ”λ°, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•˜μŠ€μΌˆ 같은 순수 ν•¨μˆ˜ν˜• μ–Έμ–΄κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μ§„μ§œ ν•¨μˆ˜ν˜• μ–Έμ–΄μ˜ 핡심인 컀링, λ©”λͺ¨ν™”, λŠκΈ‹ν•œ 평가, λΆˆλ³€μ„± 등을 ν‰λ‚΄λ‚΄κΈ°μœ„ν•΄ μ‚¬μš©ν–ˆλ‹€. 라이브러리λ₯Ό μ‚¬μš©ν•¨μœΌλ‘œμ¨ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ κΈ°λ²•λ“€μ˜ λ‚΄λΆ€λ₯Ό μΌκ΄€λœ λ°©ν–₯으둜 μΆ”μƒν™”ν•˜κ³  κ°„λ‹¨ν•œ ν•¨μˆ˜λ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ²Œ μœ λ„ν•˜λŠ” κ³ μˆ˜μ€€ μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜μ™€ μ–Έμ–΄μ˜ 뢀가적인 μš”μ†Œλ₯Ό μ œκ³΅ν•¨μœΌλ‘œμ¨ ν‘œμ€€ μžλ°”μŠ€ν¬λ¦½νŠΈ ν™˜κ²½κ³Όμ˜ 격차λ₯Ό μ€„μ˜€λ‹€.

 

μ„ μ–Έν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ μž₯점은 μ—¬λŸ¬κ°€μ§€κ°€ μžˆμ§€λ§Œ 그쀑에 ν•˜λ‚˜λ₯Ό λ½‘μžλ©΄ 좔상화가 μ•„λ‹κΉŒ μƒκ°ν•œλ‹€. ν”„λ‘œκ·Έλž¨μ˜ 좔상화 μˆ˜μ€€μ„ λ†’μ—¬ μ–΄λ–»κ²Œ(How)λ³΄λ‹€λŠ” 무엇(What)을 λ‚˜νƒ€λ‚΄λŠ”μ§€μ— μ§‘μ€‘ν•˜κΈ° λ•Œλ¬Έμ— κ°„κ²°ν•˜κ³  선언적인 λ°©μ‹μœΌλ‘œ λ³΅μž‘ν•œ μž‘μ—…μ„ μ²˜λ¦¬ν•  수 μžˆμœΌλ‚˜, λ‹¨μ μœΌλ‘œλŠ” 높은 λŸ¬λ‹μ»€λΈŒμ΄λ‹€. λΆ€μˆ˜νš¨κ³Όλ₯Ό 자주 λ°œμƒν•˜λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ νŠΉμ§•(μ „μ—­ λ²”μœ„μ—μ„œ λ³€μˆ˜/속성/자료ꡬ쑰λ₯Ό λ³€κ²½, μ‚¬μš©μž μž…λ ₯을 처리, μ˜ˆμ™Έλ₯Ό μΌμœΌν‚¨ ν•΄λ‹Ή ν•¨μˆ˜κ°€ λΆ™μž‘μ§€ μ•Šκ³  κ·ΈλŒ€λ‘œ μ˜ˆμ™Έλ₯Ό 던짐, HTMLλ¬Έμ„œ, λΈŒλΌμš°μ € μΏ ν‚€, DB질의, DOM μˆ˜μ • λ“±..) 덕뢄에 λͺ¨λ“  μ½”λ“œλ₯Ό ν•¨μˆ˜ν˜•μœΌλ‘œ μž‘μ„±ν•˜κΈ°λ³΄λ‹€ λͺ…λ Ήν˜•μ μœΌλ‘œ μž‘μ„±ν•˜λŠ” 것에 μ΅μˆ™ν•΄μ Έ μžˆλŠ” κ°œλ°œμžλ“€μ€ 처음 λŠλΌλŠ” ν•¨μˆ˜ν˜• μ‚¬κ³ λ°©μ‹μ΄λΌλŠ” 벽에 λ§‰νžˆλŠ” κ²½μš°λ„ μ’…μ’… μžˆμ„ 것이닀.

728x90

✏️ 본둠

μž¬μ‚¬μš© κ°€λŠ₯ν•œ, λͺ¨λ“ˆμ μΈ μ½”λ“œλ‘œ

  1. ν˜•μ‹ν™”ν•œ νŠœν”Œ μžλ£Œν˜•
const Tuple = function (/* ν˜•μ‹ */) {
  const typeInfo = Array.prototype.slice.call(arguments); // νŠœν”Œμ— λ‹΄κΈ΄ 인수 ν˜•μ‹μ„ μ½μŠ΅λ‹ˆλ‹€.
  console.log("typeInfo :>> ", typeInfo);

  const _T = function (/* κ°’ */) {
    // λ‚΄λΆ€ν˜• _TλŠ” νŠœν”Œμ˜ ν˜•μ‹κ³Ό 값이 λ§žλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.
    const values = Array.prototype.slice.call(arguments); // νŠœν”Œμ— μ €μž₯된 값을 κΊΌλƒ…λ‹ˆλ‹€.
    if (values.some((val) => val === null || val === undefined)) {
      throw new ReferenceError("νŠœν”Œμ€ null 값을 κ°€μ§ˆ 수 μ—†μŠ΅λ‹ˆλ‹€!");
    }
    if (values.length !== typeInfo.length) {
      // μ •μ˜λœ ν˜•μƒ‰ κ°œμˆ˜μ™€ νŠœν”Œ ν•­μˆ˜κ°€ μΌμΉ˜ν•˜λŠ”μ§€ μ²΄ν¬ν•©λ‹ˆλ‹€.
      throw new TypeError("νŠœν”Œ ν•­μˆ˜κ°€ ν”„λ‘œν† νƒ€μž…κ³Ό λ§žμ§€ μ•ŠμŠ΅λ‹ˆλ‹€!");
    }
    values.forEach((val, index) => {
      // 각 νŠœν”Œ κ°’μ˜ ν˜•μ‹μ΄ μ˜¬λ°”λ₯Έμ§€ checkTypeν•¨μˆ˜λ‘œ μ‘°μ‚¬ν•©λ‹ˆλ‹€. 각 νŠœν”Œ μ›μ†ŒλŠ” ._n(μ›μ†Œ 인덱슀 n은 1λΆ€ν„° μ‹œμž‘)둜 μ°Έμ‘° κ°€λŠ₯ν•œ νŠœν”Œ μ†μ„±μœΌλ‘œ λ°”κΏ‰λ‹ˆλ‹€.
      this["_" + (index + 1)] = checkType(typeInfo[index])(val);
    }, this);
    Object.freeze(this);
  };

  _T.prototype.values = () => {
    return Object.keys(this).map((k) => this[k], this);
  };
  return _T;
};

const Status = Tuple(Boolean, String);
console.log("Status :>> ", Status());
  1. curry: λ‹€λ³€μˆ˜ ν•¨μˆ˜κ°€ 인수λ₯Ό μ „λΆ€ 받을 λ•ŒκΉŒμ§€ 싀행을 보λ₯˜, λ˜λŠ” μ§€μ—°μ‹œμΌœ λ‹¨κ³„λ³„λ‘œ λ‚˜λ‰œ 단항 ν•¨μˆ˜μ˜ μˆœμ°¨μ—΄λ‘œ μ „ν™˜ν•˜λŠ” 기법
// 두 인수λ₯Ό μˆ˜λ™μœΌλ‘œ 컀리
function curry(fn) {
  return function (firstArg) {
    // 처음 curry2 호좜 μ‹œ 첫 번째 인수λ₯Ό ν¬μ°©ν•©λ‹ˆλ‹€.
    return function (secondArg) {
      // 두 번째 호좜 μ‹œ 두 번째 인수λ₯Ό ν¬μ°©ν•©λ‹ˆλ‹€.
      return fn(firstArg, secondArg); // 두 인수 firstArg, secondArg둜 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ 결괏값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
    };
  };
}
  1. λΆ€λΆ„ 적용(partial application): ν•¨μˆ˜μ˜ 일뢀 λ§€κ°œλ³€μˆ˜ 값을 μ²˜μŒλΆ€ν„° κ³ μ •μ‹œμΌœ ν•­μˆ˜κ°€ 더 μž‘μ€ ν•¨μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” 기법
function partial() {
  let fn = this;
  let boundArgs = Array.prototype.slice.call(arguments);
  let placeholder = undefined;

  let bound = function () {
    let position = 0;
    let length = boundArgs.length;
    for (let i = 0; i < length; i++) {
      args[i] =
        boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
    }

    while (position < arguments.length) {
      args.push(arguments[position++]);
    }
    return fn.apply(this, args);
  };

  return bound;
}
  1. ν•¨μˆ˜ ν•©μ„±: λ³΅μž‘ν•œ μž‘μ—…μ„ ν•œλ° λ¬Άμ–΄ κ°„λ‹¨ν•œ μž‘μ—…μœΌλ‘œ μͺΌκ°œλŠ” κ³Όμ •
// compose κ΅¬ν˜„λΆ€
function compose() {
  let args = arguments;
  let start = args.length - 1;
  return function () {
    // composeλŠ” μ‹€μ œ 인수λ₯Ό λ„£κ³  ν˜ΈμΆœν•œ 또 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
    let i = start;
    let result = args[start].apply(this, arguments); // μ „λ‹¬λœ 인수λ₯Ό λ„£κ³  λ™μ μœΌλ‘œ ν•¨μˆ˜λ₯Ό μ μš©ν•©λ‹ˆλ‹€.
    while (i--) {
      result = args[i].call(this, result); // 이전 단계 λ°˜ν™˜κ°’μ„ λ‹€μ‹œ 인수둜 λ„£κ³  κ·Έλ‹€μŒ ν•¨μˆ˜λ₯Ό 계속 반볡 μ‹€ν–‰ν•©λ‹ˆλ‹€.
    }
    return result;
  };
}

ν•¨μˆ˜ν˜• λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž˜λ°

Rx.Observable κ°μ²΄λŠ” ν•¨μˆ˜ν˜•κ³Ό λ¦¬μ•‘ν‹°λΈŒ, 두 ν”„λ‘œκ·Έλž˜λ° 세상을 ν•˜λ‚˜λ‘œ λ¬ΆμŠ΅λ‹ˆλ‹€. 이 κ°μ²΄λŠ” 5μž₯의 map, of, join λ“± μ΅œμ†Œν•œμ˜ λͺ¨λ‚˜λ“œ μΈν„°νŽ˜μ΄μŠ€μ— ν•΄λ‹Ήν•˜λŠ” κ΅¬ν˜„μ²΄μ™€ 슀트림 μ‘°μž‘μ— νŠΉν™”λœ λ©”μ„œλ“œλ₯Ό μ—¬λŸΏ κ±°λŠλ¦½λ‹ˆλ‹€. λ‹€μŒμ€ SSN ν•„λ“œκ°’μ΄ μ˜¬λ°”λ₯Έμ§€ κ²€μ¦ν•˜λŠ” κ°„λ‹¨ν•œ μ˜ˆμ œμž…λ‹ˆλ‹€.

// AS-IS
document
  .querySelector("#student-ssn")
  .addEventListener("change", function (event) {
    let value = event.target.value;
    value = value.replace(/^\s*|\s*$|\-/g, "");
    console.log(value.length !== 9 ? "맞음" : "ν‹€λ¦Ό");
  });

// TO-BE
Rx.Observable.fromEvent(document.querySelector("#student-ssn"), "change")
  .map((x) => x.target.value)
  .map(cleanInput)
  .map(checkLengthSsn)
  .subscribe((ssn) =>
    ssn.isRight ? console.log("Valid") : console.log("Invalid")
  );

✏️ 결둠

μ–΄λ–€ 방법을 λ„μž…ν•  λ•Œ 일μž₯일단을 κ³ λ €ν•΄μ•Όν•œλ‹€. 무엇보닀 μ€‘μš”ν•œ 것은, 100% μ„ μ–Έν˜• ν˜Ήμ€ λͺ…λ Ήν˜•μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, 각각의 μž₯, 단점을 νŒŒμ•…ν•˜μ—¬ μ§€κΈˆ λ‚˜μ˜ 상황을 ν•΄κ²°ν•˜λŠ” 데 더 μ ν•©ν•œ 방법을 λ„μž…ν•˜λŠ” 것이지 μ•Šμ„κΉŒ μƒκ°ν•œλ‹€.

 

이번 사내 μŠ€ν„°λ””λŠ” λ¦¬νŒ©ν† λ§μ„ μ‹ μ²­ν–ˆλŠ”λ°, μŠ€ν„°λ”” λ•Œ μ°Έκ³ ν•˜λŠ” μ„œμ μ΄ λ¦¬νŒ©ν† λ§ 2νŒμ΄λ‹€. κ·Έλž˜μ„œ λ‹€μŒ μ„œμ μ€ λ¦¬νŒ©ν† λ§ 2판으둜 μ •ν–ˆλ‹€. (읽어야 ν•  책이 ν•˜λ‚˜ 더 μžˆλŠ”λ° κ·Έ μ•…λͺ… 높은 λ§ˆλ²•μ‚¬ 책이닀.)

 
 

 

 

λ°˜μ‘ν˜•

λŒ“κΈ€