관리 메뉴

Jerry

클래스(CLASS)란??? 본문

Front/JavaScript

클래스(CLASS)란???

juicyjerry 2021. 4. 24. 17:30
반응형
이 글은 인프런, Javascript 핵심 개념 알아보기 - JS Flow, 정재남 강의를 수강하면서 정리한 내용입니다.

 

오늘 클래스에 대해서 알아보자!

오늘도 클래스를 정복하러 가보자!

💪😎💪😎💪😎💪😎💪😎💪😎💪😎

 

출처: pixabay.com/images/id -60527/

 

 

 

 


 

 

1. 클래스

클래스는 인스턴스라는 용어와 같이 나온다.

인스턴스는 어떤 클래스의 속성을 지니고 있는 구체적인 객체 및 대상을 의미한다.

 

 

클래스상에도 상위 클래스 / 하위 클래스로 나뉠 수 있다.

아래 이미지처럼.

 

 

 

 

자바스크립트는 프로토타입 언어라고 하지만,

일단은 여기서는 인스턴스를 제외한 나머지를 클래스로 보자!

 

 

 

 

일반적인 클래스의 정의는 인스턴스를 생성하는 데에 보조하는 역할을 한다. 

Array에 있는 애들을 static methods, static properties라고 하는데, 얘네들은 클래스를 추상적인 클래스로서가 아니라 클래스를 하나의 객체로서 다룰 때 쓰는 메서드이고 prototype에 있는 메서드는 그냥 메서드 혹은 프로토타입 메서드라고 한다. 

 

 

 

 

앞서 프로토타입 시간에 이야기했듯이

this를 사용할 때 인스턴스에서 methods는 __proto__로 접근할 수 있다. 자신의 것인 것처럼!

 

근데, instance에서 static methods & static properties로 접근하지 못한다.

instance를 this로서 접근은 못하기 때문에 접근을 못 한다고 표현을 하였고, 접근을 하려면 call이나 apply, bind 같은 메서드를 사용해야 한다.

 

 

 

static method와 (prototype) method 표시를 한 코드 예시다.

 

 

 

 

 

2. CLASS INHERITANCE (클래스 상속)

각 생성자대로 따로 구분하여 사용할 수도 있겠지만, 각 생성자들에게 getName, getAge가 중복이 존재하는데..

 

 

 

 

이에 대한 방법으로, Person를 상위에 올리고 Employee를 하위로 내려서 상속 구조를 만들 수 있다.

아래 오른쪽 이미지처럼 되면, Person은 getName과 getAge에 접근이 가능하지만, getPosition에는 접근하지 못하며,

Employee는 3개 메서드에 접근이 가능하게 될 것이다.

 

 

그렇다면, 둘 간의 연결은 어떻게 시켜줄까?

Person과 Employee의 상위 클래스와 하위 클래스 구분과 연결을 아래와 같이 할 수 있다.

 

Employee.prototype = new Person()이라는 코드로 둘 사이를 연결시켜주었다.

(Employee의 프로토타입이 Person의 인스턴스면 된다)

 

하지만, 여기서 연결 시 Employee의 프로토타입은 Person의 인스턴스를 덮어 씌어주었기 때문에 원래 있던 프로토타입이 날아가면서 Employee의 constructor가 사라지기 때문에 Employee.prototype.constructor = Employee 코드로 다시 생성해준다.

 

 

 

 

이렇게 해서 Person과 Employee의 상위 클래스 하위 클래스 구분과 연결해주게 되었고 아래와 같은 구조로 표현할 수 있게 된다.

 

 

 

 

 

코드 예시를 살펴봅시다!

  1. Employee.prototype을 new Person 인스턴스로 연결을 해줌
  2. Employee.prototype.constructor를 복구해줌
  3. Employee.prototype 에게 getPosition 메서드를 부여함 (3번을 굳이 왜 마지막에 넣을까?)

    => 1번에서 덮어쓰기를 하면서 내용들이 사라질 수 있기 때문에 그 이후에 메서드를 추가를 해주었다.

 

 

 

그다음, 인스턴스를 만들어서 콘솔에 찍어주었다.

잘 만들었지만, 만약 name: "고무"를 지우게 된다면 체이닝에 의해서 name:"이름 없음"이 나올 것이다!

이렇게 출력되면 안 되는 것이다.

 

 

 

 

이에 대한 2가지 방법으로,

1. Person에 대한 인스턴스를 만들고 나서 프로퍼티를 지우는 방법이 있다.

2. 더글라스 크락포드 아저씨가 고안한, f라는 함수 객체를 쓴다. 여기선 bridge라는 생성자라고 이야길 한다.

1번은 무식한(?) 방법이고, 좀 더 세련한 방법인 2번에 대해서 살펴보자.

 

1 -> 2 -> 3

 

 

위의 과정을 순서대로 보면,

  1. Bridege라는 함수를 만듦
  2. Bridege.prototype에 Person.prototype이 가게 만듦
  3. Employee.prototype에 Bridege 인스턴스 넣어줌
  4. Employee.prototype.constructor 다시 살려줌
  5. Employee.prototype.getPosition 선언해줌

=> 결과적으로, __proto__에 있는 해당 프러퍼티가 사라진다.

 

 

 

 

아래 이미지도 같은 과정을 표현하고 있다.

 

 

 

아래 이미지의 좌상단의 패턴(Bridge 함수)은 자주 사용하는데 매번 하기 불편하니깐

아래 이미지의 우하단의 extendClass가 (위에서 언급한 2번 방법) 나오게 되었다.

 

extendClass를 보면, 즉시 실행 함수이고 함수 선언했고, 함수를 반환했다.(클로저!)

클로저인데 즉시 함수이니깐 처음에 선언한 Bridge는 이후에 다시 선언하지 않는다. 

근데 전역 콘텍스트가 종료될 때까지 살아있게 된다. 

참고로, Bridge라는 함수 안에는 아무것도 없으므로 메모리를 크게 차지하지 않는다. 

 

 

 

 

이후에 extendClass를 활용하여, 두 개의 클래스 관계를 상위 / 하위 클래스로 지정해주면 잘 연결이 된다!

 

 

자바스크립트가 클래스 언어가 아니고 프로토타입 언어임에 불구하고, 클래스처럼 동작하는 걸 흉내를 내는 것에 그쳤을 뿐인데 

그 흉내를 내는 과정이 복잡해 보이긴 했지만 그림으로 확인해보니 연결만 잘해주면 되는 거였다!

 

 

 

참고로, ES6는 클래스 성능 구현하기 위해 지금까지 과정을 구현할 필요는 없고 extends를 사용해주면 된다. 

 

 

 

반응형