[ES6] Class

sangminnn·2020년 4월 13일
0

글로 정리하는 ES6

목록 보기
10/11
post-thumbnail

개념

이전의 OOP글에서도 한번 언급했었지만,

다른 객체지향형 언어에서는 객체지향형 프로그래밍을 구현하기 위한 도구로

Class 를 사용하는 반면, Javascript는 prototype 를 사용한다.

이는 아무래도 Class기반 언어에 익숙한 프로그래머들이 Javascript를 사용할 때, 보다 더 익숙한 형태로 접근할 수 있도록 하는 목적으로 ES6에서 도입되었으며, 한가지 알아두어야 할 점은 Syntax Sugar 라는 점이다.

그렇다면 Syntax Sugar 란 무엇일까 ?

이는 이름이 주는 느낌 그대로, 새로운 기능을 만들어 낸 것이 아니라,

단지 기존의 prototype을 형태만 class 형으로 풀어서 만들어낸 것이다.

그렇다는 말은, 내부적으로는 prototype 형태로 바뀌어 동작한다는 것이다.

이제 클래스의 사용법에 대해 알아보자.

사용법

클래스 정의

기본적으로 클래스는 함수이기 때문에 선언식, 표현식 두가지 방식으로 정의가 가능하지만

클래스의 경우에서는 일반적으로는 선언식으로 정의한다.

기본적으로 명칭을 정해줄 때에는 대문자로 시작하는 Pascal Case를 적용시켜서 정의한다.

// 클래스 선언식
class Hello {
    constructor(name) {
    	this.name = name;
    }
  
  	sayHi() {
    	console.log(`hello, ${this.name}`);
    }
}

const sangmin = new Hello('sangmin');
sangmin.sayHi(); // hello, sangmin


// 클래스 표현식

let Hello = class {
    // Something ...
}

// 하지만 기명 클래스는 함수표현식과 동일하게 클래스명으로는 접근이 불가능하다.
let Hello = class Someone {
	// Something ...
}

const sangmin = new Hello(); // O
new Someone(); // X

// typeof 로 클래스를 확인하면 function이 나타난다.

console.log(typeof Hello) // function

추가적으로 위에서 언급한 Syntax Sugar에 대한 내용으로 아래의 사진을 보면 이해가 될 것이다.

console 창에서 클래스를 선언하고 console.dir로 내부구조를 확인해 본 결과

내용들이 자동으로 prototype에 들어가는 것을 확인할 수 있다.

한가지 더 알아보자면, 클래스도 호이스팅이 일어난다는 점이다.

하지만 var 로 선언하는 방식에서 일어나는 변수의 선언과 초기화가 동시에 일어나는 호이스팅이 아니라

let, const 로 선언하는 방식에서 일어나는 단순 선언적 호이스팅이 일어나기때문에

초기화 전까지는 해당 클래스는 정의되어있지 않은 상태로 남아있다.(Temporary Dead Zone)

++) 여기서 TDZ는 호이스팅은 되었으나 초기화되어있지 않은 상태에 있는 변수, 함수가 존재하는 곳을 말한다.

console.log(Hello); // Uncaught ReferenceError: Hello is not defined

class Hello { };

constructor

constructor는 인스턴스를 생성한 다음 클래스 필드를 초기화하기 위한 특수한 메소드인데

여기서 인스턴스클래스 필드 라는 용어에 대해 한번 더 알아보고 넘어가자면

인스턴스 는 new 생성자로 생성된 클래스를 가리키는 용어이고,

클래스 필드 는 클래스 내부에 있는 캡슐화된 변수를 말하는 것이다.

인스턴스의 경우, 인자로 받아오는 값을 통해 내부 값을 정해진 틀에 따라 정의하기 때문에

constructor로 인자를 내부값으로 custom하는 과정이 필요하다.

class Hello {
	constructor(name) {
    	this.name = name;
    }
  
  	sayHi() {
    	console.log(`Hello, ${this.name}!`);
    }
};

let sangmin = new Hello('Sangmin');
sangmin.sayHi(); // Hello, Sangmin!

constructor는 인스턴스의 생성과 동시에 클래스 필드의 생성 및 초기화를 실행하기 때문에,

클래스 필드를 초기화하고자 한다면 constructor를 생략하면 안된다.

그 외에 경우에 클래스 필드를 초기화하는 작업이 중요하지 않다면, 이를 생략해도 괜찮다.

생략할 경우에는 자동으로 constructor() { } 가 포함된 것처럼 동작하기 때문이다.

상속

객체지향형 프로그래밍의 장점 중 하나인 상속 또한 구현이 가능하다.

이를 구현하기 위해서는 extends 라는 키워드를 사용해서 구현할 수 있는데,

아래의 코드를 보면서 이해해보자.

class Person {
	sayHello() {
    	console.log("Hello!");
    }
}

class Sangmin extends Person {
}

let sangmin = new Sangmin();
sangmin.sayHello(); // Hello!

위 코드에서 보다시피 Person 클래스를 extends 키워드를 통해 상속받은 Sangmin 클래스를 정의해주고,

sangmin 인스턴스를 만들어 Person 클래스에 있던 sayHello 메소드를 실행시켰을 때,

상속이 잘 이루어져 Hello! 가 출력되는 것을 볼 수있다.

추가적으로 위의 상황에서 상속을 해주는 대상인 Person 클래스슈퍼 클래스(Super Class)

상속을 받는 Sangmin 클래스서브 클래스(Sub Class) 라고 부르며

이 명칭을 따라 상속받는 서브 클래스에서 constructor 를 정의하려면 반드시 super() 를 호출해야 한다.

마치며 ..

React를 사용할 때, 요즘은 점점 React hooks를 기반으로 한 함수형 컴포넌트를 주로 사용하는 추세이지만

클래스형 컴포넌트를 보다보면 종종 헷갈리는 부분이 있을 수 있다.

그렇기 때문에 ES6의 클래스 문법을 제대로 공부하고 넘어가는 것을 추천한다.

++) 오늘 글도 Jbee 님의

https://jaeyeophan.github.io/2017/04/18/ES6-6-Class-sugar-syntax/

와 poiemaweb 의 https://poiemaweb.com/es6-class 를 보며 공부한 내용을 토대로 작성한 글입니다.

profile
생각하며 코딩하려고 노력하는 개발자가 되겠습니다.

0개의 댓글