[JavaScript] 클래스(Class)와 인스턴스(instance)

iberis2·2023년 1월 13일
0

객체 지향 프로그래밍

하나의 모델(청사진)이 되는 원형 객체(class)를 만들고,
이 원형 객체를 바탕으로 여러 인스턴스(instance)들을 만들어 내는 프로그래밍 패턴을 말한다.

  • "자동차" 라는 class(원형 객체)를 만들고,
  • "아반떼", "미니", "비틀" 라는 여러 instance(인스턴스)를 만들어낼 수 있다.

class와 instance

class는 다른 함수와 구분하기 위해 보통 대문자로 시작하며, 일반명사로 만든다.

  • function 클래스이름(파라미터){ 인스턴스가 만들어질 때 실행되는 코드}
    ES5에서 클래스는 함수로 정의했지만,
  • class 클래스이름{ constructor(파라미터){인스턴스가 만들어질 때 실행되는 코드} }
    ES6에서부터 class 키워드를 이용해 정의할 수도 있다.

constructor(생성자 함수)return값을 만들지 않는다.

/* ES5에서 함수로 정의하는 방식*/
// const Car = function(){ } 함수 표현식으로 작성할 수도 있다.
function Car(brand, name, color){ 
    this.brand = brand;
    this.name = name;
    this.color = color;
}


/* ES6 이후 class로 정의하는 방식 */
class Car{
  constructor(brand, name, color){
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
}

let 인스턴스이름 = new 클래스이름(파라미터);
new 키워드를 사용해 인스턴스를 만들면, 즉시 생성자 함수(constructor)가 실행되고, 변수(인스턴스이름)에 클래스의 설계를 가진 새로운 객체가 할당된다.
인스턴스는 클래스의 고유 속성과 매서드를 갖게 된다.

class Car{
  constructor(brand, name, color){
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
}

let avante = new Car('hyundai', 'avante', 'blue');
console.log(avante);  // Car { brand: 'hyundai', name: 'avante', color: 'blue' }
console.log(avante.color); // blue

class의 매서드 정의하기

ES5 에서는 prototype 키워드를 사용해 매서드를 정의했다.
ES6 에서는 class 블록 안에 함께 정의할 수 있다.
이렇게 전달한 매서드들은 __proto__ 프로토타입 체인으로 연결된다

// ES5 의 메서드 정의
function Car(brand, name, color){ /* 생략 */ }
Car.prototype.reful = function(){             // car의 매서드
  console.log(`${this.name}의 연료를 공급합니다`);
}
Car.prototype.drive = function(){             // car의 매서드
  console.log(`${this.name}의 운전을 시작합니다`);
}

// ES6의 메서드 정의
class Car{
  constructor(brand, name, color){ /* 생략 */ }
  refuel() {                                  // car의 매서드
    console.log(`${this.name}의 연료를 공급합니다`);
  }
  drive() {                                   // car의 매서드
    console.log(`${this.name}의 운전을 시작합니다`);
  }
}

let avante = new Car('hyundai', 'avante', 'blue');
avante.refuel(); // avante의 연료를 공급합니다
avante.drive();  // avante의 운전을 시작합니다

이렇게 정의한 매서드들은 인스턴스 객체 내부(원형 객체)에서는 바로 볼 수 없고, 인스턴스객체.__proto__로 프로토타입 체인 안에서 메서드를 확인할 수 있다.

💡 만약 prototype이 아닌 this.변수 = 함수를 할당하면, 프로토타입 체인이 아닌 객체 내부 프로퍼티로 정의된다.

/* 함수 표현식으로 만들었을 때 */
const User = function (name) {
  // function User(){ } 함수 선언문으로 작성해도 동일하다
  this.name = name;
  this.greeting = function () {
    console.log(`Hi, I'm ${this.name}`);
  };
};

const user1 = new User("Joy", 20);
console.log(user1); // User { name: 'Joy', greeting: [Function (anonymous)] }
user1.greeting(); // Hi, I'm Joy


/* class 문법으로 만들었을 때 */
class Student {
  constructor(name) {
    this.name = name;
    this.greeting = function () {
      console.log(`Hi, I'm ${this.name}`);
    };
  }
}

let student1 = new Student("Joy");
console.log(student1); // Student { name: 'Joy', greeting: [Function (anonymous)] }
student1.greeting(); // Hi, I'm Joy

Array(배열)

일반적으로 만들고 사용하는 배열도 전부 Array 원형 객체의 instance 이다.

// instance 생성 방식으로 배열을 만들 수도 있다.
let fruitArray = new Array('apple', 'peach', 'orange');
console.log(fruitArray); // [ 'apple', 'peach', 'orange' ]

// 원형 객체 Array에 정의되어 있는 고유(내장) 매서드를 사용할 수 있다.
console.log(fruitArray.length); // 3
fruitArray.push('strawberry');

용어 정리

  • prototype (모델의 청사진을 만들 때 쓰는) 원형 객체(original form)를 가리킨다. 매서드들이 담겨 있다.

  • constructor 인스턴스(instance)가 초기화될 때 실행하는 생성자 함수이다.

  • this 함수가 실행될 때, 해당 scope 마다 생성되는 고유한 실행 context(execution context, 코드가 실행되기 위한 환경)을 가리킨다.
    new 키워드로 인스턴스를 생성했을 때에는, 해당 인스턴스가 바로 this의 값이 된다.

💡 매서드와 화살표 함수
일반 함수에서 this 는 함수를 호출한 객체를 가리키게 된다.
하지만 화살표함수에서는 this는 호출한 대상에 따라 상대적으로 변하지 않고, Arrow Function이 선언되기 직전에 유효한 this 값과 똑같은 값을 가지고 동작한다. 따라서 객체의 매소드를 만들 때에는 화살표 함수가 아닌, 일반함수를 사용할 것이 권장된다.

profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글