JS | Class 와 Prototype 그리고 Class 상속과 확장

imzzuu·2022년 4월 20일
0

js는 객체 지향 언어이며, prototype 기반언어이다.
그렇기 때문에 오늘 올리는 내용은 정말 중요한 내용이 될 것 같다!
앞으로도 깊이 개념을 쌓아서 강의 노트가 아닌 나만의 포스트로 올려보고 싶은 마음을 담아 강의노트를 작성한다.

Class & Prototype

🪐Class란?

조금 더 연관 있는 data (변수,함수) 들끼리 묶어둔 것 (비슷한 object 만들 일 있을 때 사용)

" fields(속성) + methods(행동_객체에 포함되어있는 함수) "가 묶여있는 것

객체를 만들 땐 아래와 같은 코드를 사용한다.

const heropy = {
  firstName: "Heropy", // 속성 property
  lastName: "Park",
  getFullName: function () {   //  method
    return `${this.firstName} ${this.lastName}`; // this === heropy
  },
};
console.log(heropy.getFullName());

const amy = {
  firstName: "Amy", 
  lastName: "Clarke",
  getFullName: function () { 
    return `${this.firstName} ${this.lastName}`; 
  },
};
console.log(amy.getFullName());

const neo = {
  firstName: "Neo", 
  lastName: "Smith",
  getFullName: function () {  
    return `${this.firstName} ${this.lastName}`; 
  },
};
console.log(heropy.getFullName());

모든 객체 데이터를 이렇게 만들어주어야 하는데, 규모가 큰 프로젝트 시 이러한 로직은 비효율적이다.

이럴 때 사용할 수 있는 것이 class다. 비슷한 구조의 객체를 찍어낼 수 있는 틀을 만드는 것이다.

아래는 생성자 함수를 통해 객체를 생성하는 코드이다.

// 암묵적으로 파스칼케이스로 작성 (앞 문자 대문자)
function User(first, last) {
  this.firstName = first
  this.lastName = last
}
//prototype 
User.prototype.getFullName = function () {  
    return `${this.firstName} ${this.lastName}`; 
  },

// 생성자 함수 => 하나의 객체 데이터를 찍어냄
const heropy = new User('Heropy', 'Park')
const amy = new User('Amy', 'Clarke')
const neo = new User('Neo', 'Smith')

// => heropy, amy, neo는 생성자 함수의 인스턴스

heropy, amy, neo를 생성자 함수의 “인스턴스” 라고 하는데,
이처럼 생성자 함수를 통해 인스턴스를 만들어 내는 것을 class 라고 한다.
위 코드를 콘솔에 찍어보면,

console.log(heropy) // user {firstName: 'Heropy', lastName: 'Park'} 객체가 찍힘
console.log(heropy.getFullName()) // 아래 사진

직접 user 객체 안에 method 로 들어가 있지는 않지만, protptype 안에 함수로 들어가 있는 것을 볼 수 있다. 메모리에 한번만 만들어진 getFullName 함수를 참조해서 사용할 수 있다는 것이다.

여기서 잠깐! Prototype에 대해 조금 더 자세히 알아보자.

🪐 Prototype 이란?

  • 유전자 / 숨겨진 공간
  • 기계 라는 class 에 유전자를 넣어줌 ⇒ 실제론 보이진 않음 (object에 직접 추가되지는 않음)
  • 하지만 자식들이 가져다 쓸 수 있음
    (Ref : 애플코딩)

first name, last name 은 변수에 따라 값이 달라지기 때문에 user 함수를 통해 관리하고,
getFullName 함수는 로직이 똑같기 때문에, prototype 을 통해 관리하면 메모리 효율이 좋다.

++) prototype은 배열에서도 사용할 수 있는데, 우리가 알고 있는 includes, filter 등 Array 내장 함수들이 여기에 method로 저장되어있기 때문에 사용 가능한 것이다.


아까 생성자 함수를 통해 새로운 인스턴스를 만드는 것이 class 라고 했는데, ES6 문법이 나오면서 이를 좀 더 직관적으로 사용할 수 있는 Class 문법에 대해 알아보자!


🪐 ES6 Class 문법의 작성법

위에서 작성한 코드를 ES6 class 문법을 통해 재 작성하면 아래와 같다.

// 이전 코드
function User(first, last) {
  this.firstName = first
  this.lastName = last
}

User.prototype.getFullName = function () {  
    return `${this.firstName} ${this.lastName}`; 
  },
// ES6 class
class User {
constructor(first, last) {
  this.firstName = first
  this.lastName = last
	}
	getFullName(){
	return `${this.firstName} ${this.lastName}`; 
	}
}
  • constructor 함수를 이용한다.
  • 특히 prototype 부분을 원시적으로 작성하지 않아도, protoypte 속성이 만들어지기 때문에 더욱 직관적이다.

🪐 class 확장 / 상속

: 이미 만들어둔 class 를 가져와 그대로 적용하거나, 추가 로직을 통해 확장할 수 있다.

const myVehicle = new Vehicle("운송수단", 2);
console.log(myVehicle); // console ===> Vehicle {name : "운송수단", wheel: "2"}

  • 위의 class 를 상속받아 그대로 사용하기
class Bicycle extends Vehicle {
  constructor(name, wheel) {
    super(name, wheel); // super를 이용해 상속 받아 사용
  } 
}
const myBicycle = new Bicycle("삼천리", 2);
const momsBicycle = new Bicycle("세발", 3);

console.log(myBicycle);
console.log(momsBicycle);

  • 추가 로직을 작성하여 확장

class Car extends Vehicle {
  constructor(name, wheel, license) {
    super(name, wheel);
    this.license = license;  // 추가 로직 (확장)
  }
}
const myCar = new Car("벤츠", 4, true);

console.log(myCar);

0개의 댓글

관련 채용 정보