/**
 *
 * 코드팩토리 JavaScript 강의 오답노트
 *
 */

// 1. nested function
const arrowMultiply = (x) => (y) => (z) => `x: ${x}, y: ${y}, z: ${z}`;
console.log(arrowMultiply(2)(3)(4));

function multiply(x) {
  return function (y) {
    return function (z) {
      return `x: ${x}, y: ${y}, z: ${z}`;
    };
  };
}
console.log(multiply(5)(6)(7));

// 2. arguments와 rest parameter
const multiplyAll = function (...arguments) {
  return arguments.reduce((acc, cur) => acc * cur, 1);
};
console.log(multiplyAll(1, 2, 3, 4, 5));

const multiplyAll2 = (...arguments) =>
  arguments.reduce((acc, cur) => acc * cur, 1);
console.log(multiplyAll2(1, 2, 3, 4, 5));

const multiplyAll3 = (...arguments) => {
  return Object.values(arguments).reduce((acc, cur) => acc * cur, 1);
};
console.log(multiplyAll3(1, 2, 3, 4, 5));

// 3. try, catch, throw
function divide(x, y) {
  try {
    if (y === 0) {
      // throw문을 던지면 catch문으로 이동
      throw new Error('0으로 나눌 수 없습니다.');
    }
    return x / y;
  } catch (error) {
    console.log(error);
  } finally {
    console.log('y에 0을 넣지 않았는지 다시 확인해 주세요.');
  }
}
console.log(divide(4, 0));
/* Error: 0으로 나눌 수 없습니다.
    at divide (js/test.js:35:13)
    at Object.<anonymous> (js/test.js:40:13)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47
y에 0을 넣지 않았는지 다시 확인해 주세요.
undefined
 */

console.log(divide(4, 2));
/*
y에 0을 넣지 않았는지 다시 확인해 주세요.
2
*/

// 4. class
class IdolModel {
  /* 생략 가능
  name;
  year;
  */

  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
  sayName() {
    console.log(`My name is ${this.name}`);
  }
}

const yuJin = new IdolModel('YuJin', 2003);
console.log(yuJin); // IdolModel { name: 'YuJin', year: 2003 }
console.log(yuJin.name); // YuJin
console.log(yuJin.year); // 2003
yuJin.sayName(); // My name is YuJin

console.log(typeof IdolModel); // function
console.log(typeof yuJin); // object
console.log(yuJin instanceof IdolModel); // true

// 5. getter, setter, private, protected
class IveMembers {
  #name; // private 프로퍼티, Private field '#name' must be declared in an enclosing class. (생략 불가, 반드시 클래스 내부에서 선언해야 함)
  // _year; // protected 프로퍼티(생략 가능)

  constructor(name, year) {
    this.#name = name; // 이름을 저장하기 위한 프라이빗 프로퍼티로 밑줄을 사용
    this._year = year;
  }

  /** getter: 일반적인 프로퍼티처럼 사용하지만 메서드로 동작
   * 1) 데이터를 가공해서 새로운 데이터를 반환할 때
   * 2) private한 값을 반환할 때(원래는 private한 값은 접근 불가능하지만 getter를 사용하면 접근 가능)
   */
  get age() {
    return `${this.#name}의 만 나이는 ${
      new Date().getFullYear() - this._year
    }입니다.`; // 내부 이름 _name을 사용하여 접근
  }

  get name() {
    return this.#name;
  }

  /** setter: 프로퍼티 값을 설정할 때 사용
   * 1) setter 메서드는 반드시 하나의 매개변수를 가져야 함
   * 2) setter 메서드는 값을 반환하지 않음
   * 3) immutable programming을 위해 setter 메서드를 사용하지 않는 것이 좋음
   */

  set name(newName) {
    this.#name = newName; // 내부 프로퍼티를 올바르게 설정
  }
}

const eseo = new IveMembers('eseo', 2007);
// getter를 사용하여 나이 출력
console.log(eseo.age); // eseo의 만 나이는 17입니다.

// setter를 사용하여 이름 변경
eseo.name = 'YooJin'; // setter를 올바르게 사용
console.log(eseo.name); // "YooJin"이라고 출력
profile
공부하는 개발자

0개의 댓글