on
[Javascript] #7. Javascript Class
[Javascript] #7. Javascript Class
안녕하세요, 개발자 iGon 곤잘레스입니다! 오늘은 자바스크립트의 Class에 대하여 알아보고자 합니다. Class는 ES6 이전의 모던 자바스크립트 환경에서는 없었으나, ES6에서부터 해당 기능을 지원하기 시작하였습니다. 이 때문에 익스플로러 브라우저에서는 해당 기능을 지원하지 않고 크롬이나 에지 같은 최신 브라우저 환경에서 사용이 가능합니다. Class 역시 하나의 객체로서 자바의 Class와 같이 코드의 그룹화 및 재사용성을 위해 사용합니다. 지금부터 이 Class에 대해서 알아보도록 하겠습니다.
1. 클래스 선언
기본적으로 클래스는 class 키워드를 사용하여 작성합니다. 키워드와 함께 클래스의 이름을 명명하고 블록으로 감싸게 되면 해당 클래스를 선언할 수 있습니다. 주의할 점은 클래스는 함수 선언과 다르게 호이스팅이 일어나지 않기 때문에 클래스를 작성하기 전에 클래스 생성자를 선언하면 참조 오류가 난다는 것입니다. 이 점 주의하여 클래스를 선언하시기 바랍니다.
// class 선언 /* class 클래스명 { // 생성자 함수 constructor(초기화 값) { } } */ class Example { constructor(id, name) { this.id = id; this.name = name; } } // Class 객체를 생성하기 위해서는 new 키워드를 사용하여 해당 클래스 객체를 생성 var _example = new Example('igon', '곤잘레스'); console.log('id: ', _example.id); console.log('name: ', _example.name);
기본적인 클래스 선언문은 위의 예시와 같이 작성하시면 생성하실 수 있습니다. 클래스 선언 시, 클래스명의 맨 앞글자는 대문자를 사용하시는 것이 암시적인 명명 규칙입니다. 클래스를 선언하고 선언된 클래스를 객체로 생성하여 사용하고 싶으시다면 new 키워드를 사용하여 객체를 생성하신 후, 사용하시면 됩니다. 객체로 선언하고 나면 해당 객체의 인스턴스에 직접 접근하여 사용하실 수 있으신데요. 위의 예시에서 보면 id와 name 인스턴스를 생성자 내에서 파라미터로 받아 할당하여 사용하였는데, 해당 인스턴스에 접근하기 위해서는 클래스. 인스턴스로 꺼내어 쓰시면 해당 인스턴스를 직접 사용하실 수 있으십니다
2. Constructor(생성자)
생성자 메서드는 클래스 객체를 생성하고 초기화하기 위한 함수입니다. 해당 생성자는 클래스 내에서 한 개만 존재할 수 있으며, 여러 개의 생성자를 작성하면 구문 오류가 발생하게 됩니다.
3. 속성(Field)과 메서드(Method)
클래스 내부에는 속성과 메서드를 선언하여 클래스 객체의 기능을 다채롭게 할 수 있습니다. 이러한 속성과 메서드는 객체를 필요할 때마다 생성하여 상황에 맞게 재사용하여 다양한 로직을 수행할 수 있게 합니다.
class HumanObject { constructor(name, sex) { // 클래스 속성 this.name = name; this.sex = sex; } // 클래스 메서드 getObjectInfo() { return `제 이름은 ${this.name}이며, 성별은 ${this.sex}입니다.`; } } const manObj = new HumanObject('곤잘레스', '남자'); const womanObj = new HumanObject('수진', '여자'); console.log(manObj.getObjectInfo()); // 제 이름은 곤잘레스이며, 성별은 남자입니다. console.log(womanObj.getObjectInfo()); // 제 이름은 수진이며, 성별은 여자입니다.
위의 예시를 통해 이름이 '곤잘레스'이며 성별이 '남자'인 클래스 객체 하나와 이름이 '수진'이며 성별이 '여자'인 객체 하나를 각각 생성하였습니다. 각 클래스 객체는 이름(name)과 성별(sex) 속성이 있고 getObjectInfo라는 메서드를 가지고 있습니다. 이를 각각 클래스의 인스턴스 속성과 인스턴스 메서드라고 하며, 클래스 메서드 내부에서 정의된 속성과 메서드를 가리킵니다.
4. 정적 메서드와 속성
앞의 예시에서 클래스 내부에 속성과 메서드를 인스터스화하였습니다. 하지만 static 키워드를 사용하여 작성한 속성과 메서드는 앞의 예시와 달리 인스턴스화 하지 않고 새로 생성된 클래스 객체에서도 해당 속성과 메서드를 호출할 수 없습니다. 또한 static 속성은 static 메서드 내부에서만 접근이 가능합니다.
class HumanObject { constructor(name, sex) { this.name = name; this.sex = sex; } static species = '사람'; getObjectInfo() { return `제 이름은 ${this.name}이며, 성별은 ${this.sex}입니다.`; } static getSpecies() { return `저는 ${species} 입니다.` } } const humanBeing = new HumanObject(); cosnole.log(humanBeing.species) // undefined humanBeing.getSpecies(); // undefined console.log(HumanObject.species) // 사람 console.log(HumanObject.getSpecies()); // 저는 사람입니다.
이러한 정적 속성은 인스턴스로 복제할 필요가 없는 고정 속성이나 유틸리티 함수를 생성하는 데 주로 사용됩니다. 또한 보통의 인스턴스 메서드와 정적 메서드의 차이점은 인스턴스 메서드 내에서 this 객체를 반환하게 되면 생성된 클래스 객체를 반환하지만, 정적 메서드는 선언한 클래스 자체를 반환합니다.
5. Private(ES2019 이후)
클래스 내 선언된 필드(속성)들은 모두 Public 속성이기 때문에 객체 생성 후에는 해당 속성에 직접 접근이 가능했습니다. 하지만 ES2019이후에 # prefix를 이용하여 private 속성을 사용할 수 있게 되었습니다. private 속성은 클래스 생성자 내부에서만 접근이 가능하고, 새로 생성된 클래스 객체에서는 해당 필드에는 접근이 불가합니다.
class Example { #privateItem = "으음" getPrivateItem() { return this.#privateItem } } const ex = new Example(); console.log(ex.getPrivateItem()); // 으음 console.log(ex.#privateItem); // 구문 오류
만약, private 필드를 외부에서 직접 접근하게 된다면 구문 오류가 발생하여 해당 코드가 작동하지 않을 수 있습니다. private 메서드는 역시 외부에서 직접 접근하면 오류가 발생하나, class 인스턴스로 함수로부터 접근이 가능합니다. 또한 뒤에 나올 상속(extends)과 앞에서 알아본 정적(static) 키워드를 사용할 때는 this 사용에 대해서 주의하실 점이 있습니다.
class Example { #privateMethod() { return 'privateMethod'; } publicMethod() { return this.#privateMethod(); } static #privateStaticMethod() { return 'privateStaticMethod'; } static publicCallThis() { console.log(this.#privateStaticMethod()); } static publicCallClass() { console.log(Example.#privateStaticMethod()); } } class DerivedExample extends Example {}; const newDerivedExmple = new DerivedExample(); console.log(newDerivedExmple.publicMethod()); // 'privateMethod' DerivedExample.publicCallThis(); // 타입 오류 발생 DerivedExample.publicCallClass(); // 'privateStaticMethod'
위의 예시에서 this로 호출한 로직이 오류가 나는 이유는 Example 클래스를 상속하면서 새로운 클래스인 DerivedExample 클래스를 선언하였는데, DerivedExample로 호출하게 되었을 때 this는 DerivedExample를 가리키게 되기 때문입니다.
6. 상속(Extends)
클래스의 가장 큰 장점은 상속을 통하여 새로운 자식 클래스를 생성하고 해당 클래스를 재정의 함으로써, 코드의 모듈화와 재사용성이 가능하게 된다는 것입니다. 클래스의 상속은 extends 키워드를 이용하여 상속할 수 있고, 단일 클래스에 대해서만 상속이 가능합니다.(복수 상속 불가)
class HumanBeing { constructor(name) { this.name = name; }; getInfo() { console.log(this.name); } } class Man extends HumanBeing { constructor(name, sex) { // super class를 호출하여 name 속성 전달(this보다 우선하여 super를 호출) super(name); this.sex = sex; } // 메소드 오버라이딩 getInfo() { console.log(this.name, this.sex); } } const human = new HumanBeing('아무것도 아님'); human.getInfo(); // 아무것도 아님 출력 const man = new Man('iGon', '남자'); man.getInfo(); /// iGon, 남자 출력
또한, super 키워드를 통해 부모가 가지고 있는 메서드를 자식 클래스에서 호출할 수 있습니다.
class Parent { speak() { console.log('차 조심해라'); } } class Children extends Parent { speak() { super.speak(); console.log('알겠습니다'); } } const child = new Children(); child.speak(); // 차 조심해라 // 알겠습니다 (순차적으로 호출)
지금까지 자바스크립트의 클래스에 대해 기초적인 내용을 알아보았는데요. class 기법 역시 자바스크립트 내에서 중요한 로직 작성 방법이기 때문에 이에 대한 심화된 내용은 추후에 더 깊게 알아보는 시간을 갖도록 하겠습니다. 다음 포스팅에서는 자바스크립트의 this에 대해 작성하도록 하겠습니다. 지금까지 긴 글 읽어주셔서 감사합니다.
from http://igonnnnn.tistory.com/14 by ccl(A) rewrite - 2021-12-29 00:01:52