[JavaScript] 클래스와 인스턴스, 프로토타입

jungmin Lee·2023년 7월 4일
0

클래스(Class)는 데이터와 이를 조작하는 코드를 하나로 추상화하며 객체를 생성할 수 있는 템플릿으로 객체지향 프로그래밍을 할 수 있으며 클래스를 통해서 만들어진 객체를 인스턴스(Instance)라고 한다
클래스를 만드는 새로운 문법이 ES6에 도입되었으며 최근에는 ES6 방법을 주로 사용하고 프로토타입보다 간단하게 사용할 수 있다고 한다.


클래스(Class)

클래스의 인스턴스를 만들 때에는 new 키워드를 사용하며 즉시 생성자 함수가 실행되고 변수에 클래스의 설계를 가진 인스턴스가 할당된다. 각각의 인스턴스는 클래스의 고유한 속성과 메서드를 갖게 된다. ES6에서는 생성자 함수와 함께 class 키워드 안쪽에 묶어서 정의하며 아래와 같이 작성할 수 있다. 객체지향 프로그래밍에서 등장하는 this라는 키워드가 있는데 this는 인스턴스 객체를 의미한다.
✨ 생성자 함수란?
객체지향 프로그래밍에서 생성자함수라고 부르며 인스턴스가 만들어질 때 실행되는 코드이다. 참고로 생성자 함수는 return 값을 만들지 않는다.

class Counter {
  constructor() {
    this.value = 0; 
  }
  increase() {
    this.value++
  }
  decrease() {
    this.value--
  }
  getValue() {
    return this.value
  }
}

let counter1 = new Counter()
counter1.increase()
counter1.getValue()

정적 메서드 static

static 키워드는 정적 메서드이며 클래스의 인스턴스에서는 호출할 수 없다. 정적 메서드는 클래스에 속한 함수를 구현할 때 주로 사용된다고 한다.

class calculator {
    constructor(quantity, price){
        this.quantity = quantity
        this.price = price;
    }
    static calculate(quantity, price) {
        return quantity * price
    }
}

const myCalculator = new calculator(5, 10);
const totalPrice = calculator.calculate(5, 10);

console.log(totalPrice) // Output: 50
console.log(myCalculator.quantity); // Output: 5
console.log(myCalculator.price); // Output: 10
myCalculator.calculate; // undefined를 확인할 수 있으면 클래스의 데이터를 가져올 수 없다.

Private 필드

private 필드는 #을 붙여서 사용할 수 있는데 클래스의 외부에서 접근하려고 하면 오류가 발생한다. 클래스 내부에서만 읽고 쓰기가 가능하다.

class Student {
    #name;
    #grade;
    constructor(name, grade){
        this.#name = name;
        this.#grade = grade
    }

    #display = () => {
       console.log(`${this.#name}:${this.#grade}`);
    };
}

const jimin = new Student('Jimin', '3')
console.log(jimin);

접근자 프로퍼티

클래스도 getter와 setter를 리터럴을 사용해 만든 객체처럼 지원한다. get은 속성의 값을 꺼낼 때 실행되며 set은 속성의 값을 저장할때 실행된다.

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    get fullName() {
        return `${this.firstName} ${this.lastName}`;
    }

    set fullName(value) {
        const [lastName, firstName] = value.split(' ');
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

const person1 = new Person('정민', '이');
console.log(person1.firstName); // 정민
console.log(person1.fullName); // 이정민

person2.fullName = '이민경';
console.log(person2.lastName);  // 민경
console.log(person2.fullName); // 이민경

extends를 통한 클래스 상속

extends 키워드로 자식 클래스를 생성하는데 사용할 수 있다. 부모 클래스로부터 상속을 받는 부분은 Super()를 호출해야 하며 오버라이딩도 가능하다.

class Animal {
  constructor(name) {
    this.name = name;
  }
  eat() {
    console.log("밥을 먹는다");
  }
  sleep() {
    console.log("잠을 잔다");
  }
}

class Cat extends Animal {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
  snack() {
    console.log("츄르를 먹자!");
  }
  // 오버라이딩 
  sleep() {
    super.sleep();
    console.log("캣타워에서 자고 있다");
  }
}

const cat = new Cat("젤리", "1");
console.log(cat); 
cat.play(); 
cat.eat();

ES5 클래스 작성 문법과 ES6 클래스 작성 문법

ES5는 프로토타입이라는 키워드를 사용해야 메서드를 정의할 수 있으며 일반 함수가 new 연산자와 함께 호출 시 생성자 함수로 동작한다. ES6에 도입된 새로운 문법의 클래스는 class키워드로 본문 영역 내에 constructor 키워드를 통해 생성자를 정의하며 본문 영역내에 function이라는 키워드를 생략하더라도 모두 메서드로 인식하여 프로토타입보다 간단하게 사용할 수 있다고 한다.

//ES5 클래스 문법 예시
function Car(brand, name, color) {
  this.brand = brand;
  this.name = name;
  this.color = color;
}

Car.prototype.refuel = function() {
  // 연료 공급을 구현하는 코드
}

Car.prototype.drive = function() {
  // 운전을 구현하는 코드
}

프로토타입

자바스크립트는 프로토타입을 베이스로 한 객제 지향 프로그램이며, 프로토타입은 "원형 객체"를 의미한다. 자바스크립트에서 object는 내부에 숨겨진 프로토타입을 가지고 있으며 객체를 상속하기 위하여 프로토타입이라는 방식을 사용한다. 상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있다.
외부에서 직접 접근이 불가하며 __proto__로 접근할 수 있고 생성자 함수의 경우는 예외로 prototype으로 접근이 가능하다 . 배열은 Array클래스의 인스턴스이며, Array 프로토타입도 객체이다. object프로토타입을 상속하고 있으며 객체에서 사용할 수 있는 함수들을 사용할 수 있다.

class Human {
  constructor(name) {
    this.name = name;
  }

  study() {
    console.log(`${this.name} - 공부중입니다`);
  }
}

let jungmin = new Human('jungmin');

Human.prototype.constructor === Human; // true
Human.prototype === jungmin.__proto__; // true
Human.prototype.sleep === jungmin.study; // true

Human 클래스의 생성자 함수는 Human이며, Human 클래스의 프로토타입은 Human 클래스의 인스턴스인 jungmin의 __proto__이다. Human 클래스의 study 메서드는 프로토타입에 있으며, Human 클래스의 인스턴스인 jungmin의 jungmin의.study 사용할 수 있다.
jungmin의 프로토타입 객체인 Human()에 정의된 name를 볼 수 있으며 toString, valueOf처럼 Human()의 프로토타입 객체인 object에 정의된 다른 메서드도 볼 수 있다. 여기서, 프로토타입 체인이 동작한다는 걸 알 수 있다.

profile
Leejungmin

0개의 댓글