💡 class, object 그리고 그 둘의 차이점 / 객체지향언어에 대해 공부해보자!



데이터 클래스 라고 부름🙄 강의가 끝난 후
내가 사물과 물체들을 어떻게 클래스로 만들 수있을지 생각해보는 시간을 가져보자!
쇼핑몰을 만들 때, 수강 신청 프로그램을 만들 때 어떻게 클래스로 잘 정리할 수 있을지 한번 생각해보자!




syntactical sugar(가짜의 편리함) 라고 부름class Person {
  // constructor
  constructor(name, age) {
    // field
    this.name = name;
    this.age = age;
  }
  // methods
  speak() {
    console.log(`${this.name}: hello!`);
  }
}
class라는 키워드를 이용해서 클래스를 생성constructor 생성자를 이용해서 나중에 object를 생성할 때 필요한 데이터를 전달한다.fields인 name과 age에 우리가 전달받은 데이터를 바로 할당해준다.fields가 있고, speak()라는 말하는 메소드도 존재한다.// 오브젝트 생성하기
const ellie = new Person('ellie', 20);
console.log(ellie);
console.log(ellie.name);
console.log(ellie.age);
ellie.speak();
new라는 키워드를 쓴다.
class User {
  constructor(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
}
-1이라고 설정함// 실수로 나이를 -1로 지정함
const user1 = new User('Steve', 'Job', -1);
console.log(user1);
-1이라고 설정되어 있음
-1이 될 수 없음Getter and Setters 이다.class User {
  constructor(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
  get age() {
    return this.age;
  }
  set age(value) {
    this.age = value;
  }
}
get이라는 키워드를 이용해 값을 리턴하고, set이라는 키워드를 이용해서 값을 설정할 수가 있다.set은 값을 설정하기 때문에 value를 받아와야만 한다.get age()를 호출하게 되면 우리는 this.age를 리턴해야하고,this.age를 새로운 value로 설정하게 된다.
call stack이 초과되었다는 에러 메세지가 뜬다.
age라는 getter를 정의하는 순간 this.age는 메모리에 올라가 있는 데이터를 읽어오는 것이 아니라, 바로 getter를 호출하게 된다.= age를 호출 할 때, 즉 값을 할당 할 때, 바로 메모리의 값을 할당하는 것이 아니라 set age라는 setter를 호출하게 된다.this.age에 할당 할 때 메모리의 값을 업데이트하는 것이 아니라 이 setter를 호출하게 되는 것 -> 즉 = value는 계속해서 setter를 호출하는 무한정 반복이 생기는 것_ 언더바 많이 사용)class User {
  constructor(firstName, lastName, age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
  get age() {
    return this._age;
  }
  set age(value) {
    this._age = value;
  }
}
set age(value) {
    if (value < 0) {
      throw Error ('age can not be negative');
    }
    this._age = value;
  }

set age(value) {
    this._age = value < 0 ? 0 : value;
  }

_age이지만 우리가 .age라고 호출할 수 있는 것, .age에 값을 할당할 수 있는 것은 바로 내부적으로 getter와 setter를 이용하기 때문이다.
class Experiment {
  publicField = 2;
  #privateField = 0;
}
const experiment = new Experiment();
console.log(experiment.publicField); // 2
console.log(experiment.privateField); // undefined
# 해쉬 기호를 붙이게 되면 Private Field -> 클래스 내부에서만 값이 보여지고, 접근되고, 값이 변경이 가능하지만 외부에서는 이 값을 읽을 수도 변경할 수도 없음class Article {
  static publisher = 'Dream Coding';
  constructor(articleNumber) {
    this.articleNumber = articleNumber;
  }
  static printPublisher() {
    console.log(Article.publisher);
  }
}
static이라는 키워드를 사용하면 오브젝트에 상관없이 클래스 자체에 연결되어 있다.const article1 = new Article(1);
const article2 = new Article(2);
console.log(article1.publisher); // undefined
console.log(Article.publisher); // Dream Coding
Article.printPublisher(); // Dream Coding
article1과 article2라는 object를 만들게 되면static 키워드 사용하지 않았더라면 console.log(article1.publisher); 출력 가능했을 것 -> 그러나 static 때문에 undefined 출력static은 object 마다 할당되어지는 것이 아니라 클래스 자체 즉 Article이라는 클래스 자체에 붙어있기 때문이다.static 함수를 호출 할 때도 클래스 이름을 이용해서 호출한다.static과 static method를 이용해서 작성하는 것이 메모리의 사용을 조금 더 줄여줄 수 있다.Shape이라는 class가 존재class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }
  draw() {
    console.log(`drawing ${this.color} color of`);
  }
  getArea() {
    return width * this.height;
  }
}
Rectangle 이라는 클래스를 만들고 싶다면 동일한 부분을 계속 작성하기 보다는extends라는 클래스를 이용해서 Shape을 바로 연장한다.class Rectangle extends Shape {}
class Triangle extends Shape {}
Shape에서 정의한 fields와 methods가 자동적으로 포함이된다.const rectangle = new Rectangle(20, 20, 'blue');
console.log(rectangle);
rectangle.draw();
const triangle = new Triangle(20, 20, 'yellow');
console.log(triangle);
triangle.draw();

console.log(rectangle.getArea()); // 400
console.log(triangle.getArea()); // 400
overriding 오버라이딩이라고 한다.class Triangle extends Shape {
  getArea() {
    return this.width * this.height / 2;
  }
}
console.log(triangle.getArea()); // 200
class Triangle extends Shape {
  draw() {
    console.log('🔺');
  }
  getArea() {
    return this.width * this.height / 2;
  }
}
draw메소드를 오버라이딩 해서 다른 문구가 출력되게 할 수도 있다.
draw메소드를 오버라이딩 하니까, Shape에 정의 된 draw함수가 호출되지 않음super 부모의 draw라는 함수를 호출하면된다.class Triangle extends Shape {
  draw() {
    super.draw();
    console.log('🔺');
  }
  getArea() {
    return this.width * this.height / 2;
  }
}

instanceOf operator : class checkingconsole.log(rectangle instanceof Rectangle); // T
console.log(triangle instanceof Rectangle); // F
console.log(triangle instanceof Triangle); // T
console.log(triangle instanceof Shape); // T
console.log(triangle instanceof Object); // T
triangle는 Object의 인스턴스 인가? trueObject를 상속한 것Object
console.log(triangle.toString()); // [object Object]
Triangle에서 오브젝트 안에 공통적으로 있는 함수를 오버라이딩도 할 수 있음class Triangle extends Shape {
  draw() {
    super.draw();
    console.log('🔺');
  }
  getArea() {
    return this.width * this.height / 2;
  }
  toString() {
    return `Triangle: color: ${this.color}`
  }
}
[object Object] -> Triangle: color: ${this.color}
: 자바 스크립트의 내부에 포함되어 있는 object들에는 어떤 것들이 있는지 카테고리로 묶여져 있다!
promise -> Control abstraction➕ 추가적으로 공부하기
1.syntactical sugar찾아보기
2. 프로토타입 베이스에 링크된 글 읽고, 추가 궁금한 것 찾아보기!
3. 오버라이딩 찾아보기
4. 자바스크립트 mdn reference 페이지 공부하기
5. 이 사이트 참고해서 읽어보기