TIL - 클래스, 인스턴스, 객체

moontag·2022년 5월 25일
0

JavaScript TIL

목록 보기
17/20
post-thumbnail




🔮 요약

Class 클래스
: 설계도, 틀, 템플릿.    ex) 붕어빵 틀


Object 객체
: 설계도로 구현할 대상. class의 instance. ex) 붕어빵

  • 클래스로 선언됐을 때


    Instance 인스턴스
    : 설계도로 구현된 실체.    ex) 슈크림붕어빵
  • 메모리에 할당되어 실제 사용할 때
  • prototype
    청사진을 만들때 쓰는 원형 객체

  • constructor
    인스턴스가 초기화될때 실행하는 생성자 함수

  • this
    함수실행시, 해당 Scope마다 생성되는 고유한 실행 컨텍스트.
    new 키워드로 인스턴스 생성시, 해당 인스턴스가 바로 this 값이 됨


JavaScript reference




OOP란?

모델이 되는 설계도를 만들고 이를 바탕으로 객체를 만드는 프로그래밍 패턴
예) 자동차 기본설계도를 바탕으로 테슬라, 부가티, 람보르기니를 만들 수 있는 것

class - 설계도
instance - 설계도를 바탕으로 만든 객체



📄 클래스

객체를 정의하고 만들기 위한 설계도, 틀, 템플릿
예) 자동차 설계도, 쿠키 모양 틀, 붕어빵 틀

특징

1. 클래스 정의하기

  • 속성 field, 메서드 method
class User {
  constructor(firstName, lastName, age){
    // fields 속성
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    }
  
    // method 메서드
    eat() { 
      console.log(`${this.name} Welcome!`);
    }
}
  • 데이터가 들어있는 것이 아니라 틀만 정의되어 있다
  • 클래스명 : 대문자로 시작하는 일반명사

2. Getter and Setters

<예시>
우리가 자판기머신 클래스를 만든다고 가정해보자.
여기에 속성은 커피개수/ 함수는 동전넣기, 커피만들기가 있다고 해보자.

  • 그런데 사용자가 멍청하게 커피개수를 -1로 설정해버린다면?
    NO! 그래서 setter로 사용자가 -1을 넣더라도 0으로 설정해주는 거지
  • 그런데 사용자가 커피개수를 설정하는게 좋을까?
    NO! 그래서 커피개수를 private로 접근 불가능하게 하자. 캡슐화를 해야한다
// age설정을 -1로 설정하려고함, 이를 방지하기 위해 get,setter 사용
class User {
  constructor(firstName, lastName, age){
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age; // this.age : get호출/ = age : set호출
    }
  
    get age() {  // 값을 리턴
      return this._age;
    }
    set age(value){  // 값을 설정함. 할당. 그래서 value를 받아와야함
      this._age = value < 0 ? 0 : value;
    }
}
const user1 = new User('Mika', 'Hoi', -1);
console.log(user1.age); // 0
  • get과 set에 같은 변수명을 사용할 때 생기는 문제
    constructor의 this.age = age;에서
    this.age가 get을 호출하고
    = age;가 set 호출하게되는데
    set 안에 this.age = value에서
    = value도 set을 계속 호출하므로 무한반복에 빠진다
    call stack 초과됐다는 오류가 남

  • 해결방법
    getter와 setter의 변수명을 다르게 변경
    예) this._age;



3. Fields - public & private

  • 그냥 정의 - 외부에서 접근가능
  • #키워드로 정의 - 클래스외부에서 접근/변경 불가능
  • 하지만 지원하는 브라우저가 적다
  • Private fields - mdn
  • TS에서는 private 키워드가 있다
class Experiment {
  publicField = 2;
  #privateField = 0; // # 키워드로 private 정의
}
const experiment = new Experiment();
console.log(experiment.publicField);  // 2
console.log(experiment.privateField); // undefined



4. Static

들어오는 데이터와 상관없이, 클래스의 값과 메서드를 사용하기

  • object마다 할당되는 것이 아닌, class 자체에 할당됨
  • static 변수,함수 호출할때는 앞에 class명.변수명 으로 써야함
  • 들어오는 데이터와 상관없이 공통적으로 class에서 쓰는 거라면 static으로 사용 => 메모리 사용을 줄여줄 수 있다
  • ts사용 할때 유용하다
class Article {
  // static 변수
  static publisher = 'martin';  
  constructor(articleNumber) {
    this.articleNumber = articleNumber;
  }

  // static 함수
  static printPublisher() {
    console.log(Artivle.puclisher);
  }
}
const article1 = new Article(1);
const article2 = new Article(2);
console.log(article1.publisher); // undefined
console.log(Article.publisher);  // martin
Article.printPublisher(); // martin



5. Inheritance 상속

  • class 클래스명 extends 복붙할클래스명 { }
    공통된 속성, 메서드를 상속받아서 재사용 가능
  • Overriding : 재정의 => 다양성 가능해짐
class User {
  constructor(firstName, lastName, age){
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    }
  eating() {
    console.log(`${this.firstName} eating rice!`);
  }
  introduce() {
    console.log(`${this.age} years old.`);
  }
  
// extends 로 확장 - 재사용성
class Person extends User {}
class Dog extends User {
  // 오버라이딩 - 다양성
  eating() {
    console.log(`${this.firstName} eating milk!`);
  }
  introduce(){
    super.introduce();  // super로 부모의 메서드 호출
    console.log('멍멍'); 
  }
}
const person = new Person('mina', 'ha', 22);
person.eating(); // mina eating rice!
const dog = new Dog('coco', 'ha', 2);
dog.eating(); // coco eating milk!
dog.introduce();  // 2 years old.   // 멍멍
  • super :
    1. 자식클래스에서 부모클래스의 메서드 호출 가능
    2. 자식클래스에서 부모클래스의 생성자(constructor) 역할
    • 자식클래스의 생성자(constructor)에선
      반드시 super()호출한 다음, this를 사용해야 에러가 안남
class Animal {

  constructor(name) {
    this.speed = 0;
    this.name = name;
  }

  // ...
}

class Rabbit extends Animal {

  constructor(name, earLength) {
    super(name);       // 부모 생성자를 실행해줌. 안하면 에러남
    this.earLength = earLength;
  }

  // ...
}

// 이제 에러 없이 동작
let rabbit = new Rabbit("흰 토끼", 10);
alert(rabbit.name); // 흰 토끼
alert(rabbit.earLength); // 10



6. instanceof

  • 객체 instanceof 클래스명
    클래스로 만들어진 객체인스턴즈인가 아닌가?
console.log(person instanceof Person);  // true
console.log(dog instanceof Dog);  // true
console.log(dog instanceof User);  // true 상속받음 
console.log(dog instanceof Object);  // true 





클래스 정의방식

ES5 : 함수로 정의 (구식)

function Car(color){
  //인스턴스가 만들어질때 실행되는 코드
}

ES6 : class 키워드로 정의 ✅

constructor 생성자 : 인스턴스가 만들어질 때 실행되는 코드

class Car{
	constructor(brand, name, color){
        //인스턴스가 만들어질때 실행되는 코드
    }
}




🍪 인스턴스

클래스의 설계도, 틀로 구현된 구체적 실체

  • 메모리에 할당되어 실제 사용할 때.
    예) 부가티, 초코쿠키, 슈크림붕어빵
  • new 키워드로 인스턴스 생성
    생성자 함수가 실행되어 변수에 클래스의 설계를 가진 새로운 객체 인스턴스가 할당된다
// Car 클래스에 avante라는 인스턴스 - 메모리에 할당
let avante = new Car('bmw', 'avante', 'red'); // avante 인스턴스
  • 클래스의 속성과 메서드를 갖는다
  • 메서드 : 객체에 딸린 함수
let avante = new Car('bmw', 'avante', 'red'); 
avante.brand; // 'bmw'
avante.refuel // 연료를 공급







this

인스턴스 객체를 의미한다

  • 속성을 정의할때 this를 사용해 인스턴스에 속성을 할당한다
class Student {
	constructor(name, age, grades) {
      this.name = name;
      this.age = age;
      this.grades = grades;
    }
}



메서드 정의방식

  • ES5 - prototype 키워드 사용 (구식)
function Car(brand, name, color) { 생략 }
Car.prototype.refuel = function() {

}
Car.prototype.drive = function() {

}
  • ES6 - 함수 안쪽에 constructor 정의
class Car {
  constructor(brand, name, color) { 생략 }
}













참고

드림코딩을 참고했습니다
자바스크립트 6. 클래스와 오브젝트의 차이점(class vs object), 객체지향 언어 클래스 정리 | 프론트엔드 개발자 입문편 (JavaScript ES6)

클래스 상속 - 모던 자바스크립트

JavaScript reference - mdn












profile
터벅터벅 나의 개발 일상

0개의 댓글