-
[Javascript] Class(클래스) 기본Front-End(Web)/Javascript 2020. 12. 16. 22:56반응형
위코드 Replit 과제중, Class 개념에 대해 정리가 필요하다고 생각해서 글을 쓰게 되었다.
📒 class 란?
- 객체지향(OOP, Object-Oriented Programming)
객체지향 프로그래밍이란, 프로그램을 객체(Object)들로 구성하고 서로 상호작용을 통해 구현하는 방법을 의미한다.
객체에 변수나 함수를 저장한 뒤 이를 반복적으로 사용하고자 하는 개념으로, 이 객체를 편리하게 생성하는 템플릿이 바로 Class인 것이다.
- class 정의
class를 "특별한 함수" 라고 설명한다. class 선언과 표현식으로 정의할 수 있다.(실제로 ES6 전에는 함수가 class를 대체했다.)
1) class 선언
ES6부터 class 개념이 도입되면서, class는 아래와 같이 'class 클래스명' 구문으로 생성할 수 있다.
class Rectangle { // Rectangle 이라는 이름의 class constructor(height, width) { this.height = height; this.width = width; } }
class에는 반드시 constructor(생성자)라고 하는 키워드를 사용해야 한다. (밑의 class 구조에서 자세히 알아보장!!)
또한, class는 함수와 달리 Hoisting이 적용되지 않아 먼저 선언을 해야한다.
2) class 표현식
// unnamed let Rectangle = class { constructor(height, width) { this.height = height; this.width = width; } }; console.log(Rectangle.name); // 출력: "Rectangle" // named let Rectangle = class Rectangle2 { constructor(height, width) { this.height = height; this.width = width; } }; console.log(Rectangle.name); // 출력: "Rectangle2"
변수에 class 를 지정하는 방법이다. Class 표현식은 이름을 변수명으로 대체가능하며, 이름은 'Class.name' 속성으로 확인가능하다.
- class 기본 문법
class User { // 클래스명 constructor(name) { // 생성자 함수 this.name = name; } sayHi() { // 메소드(함수) alert(this.name); } } let user = new User("John"); // 인스턴스 user.sayHi();
1) 클래스명 : User 에 해당하는 부분. 표현식의 경우 변수명으로 대체될 수 있다. (클래스명은 반드시 대문자로 시작, CammelCase)
2) constructor(생성자) 함수 : constructor(name) { this.name = name; } 에 해당하는 부분.
클래스 내 함수(메서드)에서 사용할 인자(argument)들을 설정하는 부분이다.
왼쪽은 this(클래스로 생성된 인스턴스)의 'name' property를 의미, 오른쪽은 인스턴스에서 입력받을 생성자값을 의미한다.
3) Method(메서드) : sayHi() { alert(this.name); } 에 해당하는 부분. 생성자를 활용한 다양한 기능을 구현하는 함수들을 의미한다.
4) Instance(인스턴스) : let user = new User('John') 에 해당하는 부분. 클래스를 통해 생성된 객체를 의미한다.
'user' 가 객체명이 되고, new 클래스명(키워드) 로 선언할 수 있다. ('John' 키워드 -> constructor 함수 -> 'name' property에 할당)
📒 Prototype 에 대한 이해
Javascript에서 함수를 정의하면, 함수 안에 Prototype Object도 같이 생성된다. (객체를 생성해도 [[Prototype]] 내부 프로퍼티가 존재)
function Foo() { }
- prototype : 생성자 함수(Foo)를 통해 형성되는 모든 객체(인스턴스)가 공유할 원형(의 정보)를 담고 있다.
- constructor : 내가 선언한 생성자 함수(Foo) 자체를 의미한다. new 구문을 쓰면 이 생성자 함수를 실행해서 객체가 생성된다.
- __proto__ : [[Prototype]] 링크를 담고 있는 객체로, 생성자 함수(Foo)의 prototype을 참조할 수 있는 경로이다.
const f1 = new Foo(); const f2 = new Foo(); Object.getPrototypeOf(f1) === Foo.prototype; // true
Foo라는 생성자 함수는 Foo.prototype 객체를 형성하고, 여기에 함수에 관한 정보들이 저장된다. (클래스에선 메소드들이 해당되겠죠?)
new 구문을 통해 새로 생성된 인스턴스(f1, f2)들은, [[Prototype]] 링크를 통해 Foo.prototype 객체와 연결된다.
이 경로를 통해, 클래스(Foo)와 인스턴스(f1, f2)는 객체간 연결이 성립되고, 클래스에 내장된 다양한 정보들을 공유할 수 있는 것이다.
📒 class의 다양한 기능들
1. Getter & Setter
class에서 사용되는 메소드의 일종이다. 인스턴스를 통해 입력된 값을 확인(get)한뒤 오류여부에 따라 값을 조정(set)하는 기능을 제공한다.
class User { constructor(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } get age() { // getter : age값을 _age에 받음(변수명 반드시 다르게 설정!) return this._age; } set age(value) { // setter : _age값 판단. 음수는 0, 나머지는 value(value가 입력값) this._age = value < 0 ? 0 : value; } } const user1 = new User('taehyung', 'Kim', -1); console.log(user1.age); // 0
2. Public, Private Fields
클래스 안에서 자체적인 변수들을 선언하는 경우이다. Public 변수는 전역에서 호출 가능하나, Private 변수(#)은 클래스 외부에선 호출불가.
class Experimet { publicfield = 2; #privatefield = 1; } const experiment = new Experimet(); console.log(experiment.publicfield); // 2 (외부접근 가능) console.log(experiment.privatefield); // undefined (외부접근 불가)
3. Static properties and methods
클래스 자체적으로만 사용될 property 나 method 를 지정하는 경우이다. (클래스 자체에선 사용가능하나, 인스턴스에선 사용불가)
class Article { static publisher = 'Dream Coding'; constructor(articleNum) { this.articleNu = articleNum; } static printPublisher() { console.log(Article.publisher); // Dream Coading (클래스 내 호출가능) } } console.log(Article.publisher); // Dream Coading (클래스 자체에서 호출가능) const article1 = new Article(1); console.log(article1.publisher); // undefined (인스턴스에선 호출 불가능!)
* Private Field(#) 나 Static 은 클래스에서 한정적으로 이용되는 설정값에 유용하며, 최근에 적용된 기능으로 사용빈도가 아직 낮다!
4. Inheritance
기존 클래스를 다른 클래스로, 말 그대로 '상속' 시키는 방법이다. (React에서 밥먹도로 쓴 'class App extends React' 가 스쳐지나갔다!🤩)
// 기존 클래스 (도형 그리기) class Shape { constructor(w,h,c) { this.width = w; this.height = h; this.color = c; } draw() { console.log(`drawing ${this.color} color of`); } getArea() { return this.width * this.height; } } // 상속 : 'extends'로 기존 클래스의 속성, 메서드를 새 클래스로 복제 class Rectangle extends Shape {} const rectangle = new Rectangle(20,20,'blue'); console.log(rectangle.getArea()); // 400 // 다양성 : 단순 복제뿐 아니라, 가져온 메서드의 수정도 가능하다 class Triangle extends Shape { // 메서드 수정방법 : 1) super(상위 Shape 클래스)의 getArea()를 받아와서, 2) return 함수로 수정 getArea() { super.getArea(); return (this.width * this.height) / 2; } } const triangle = new Triangle(20,20,'red'); console.log(triangle.getArea()); // 200
5. Obj instanceof Class
Obj 가 Class 로부터 형성됬는지 여부를 체크하는 기능. true/false를 반환한다. (inheritance 관계도 포함된다.)
// 4번 Class들 참고 console.log(rectangle instanceof Rectangle); //t console.log(triangle instanceof Rectangle); //f console.log(triangle instanceof Triangle); //t console.log(triangle instanceof Shape); //t(inheritance) console.log(triangle instanceof Object); //t(모든 Object 클래스)
😃 결론
Class는 자바스크립트 이론공부를 할 때 거의 이해를 못 한채로 넘어갔고(super, this, prototype 등등!!!),
React를 독학할 때도 클래스형 컴포넌트를 사용하며 포스팅 필요성을 절실하게 느끼고 있었다. (이해안되는 구문들이 매우 많았다.😢)
Class가 먼저 함수의 일종이지만, 그 목적자체는 객체를 '형성'함에 있다는 것을 확실히(어쩌면 새로이) 알게 되었다.
객체지향이란 개념도 이번 기회에 확실히 정립할 수 있었고, 이를 실현시키는 prototype 프로퍼티에 대해서도 많은 고민을 한 기회였다.
클래스형 컴포넌트를 제작할 때 super(props)를 사용하는것만 봐도, 클래스가 참 어렵고 그만큼 확실히 공부해야 한다고 생각했다.
이 포스팅이 클래스 이론의 절반도 채 안되겠지만, 앞으로 클래스를 다룸에 있어 가장 기초적인 개념들로 나와 지나치시는 많은 분들께 도움이 되었으면 하는 바램으로 글을 마무리한다.
출처]
- Classes MDN : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes
- 모던 Javascript 튜토리얼 : https://ko.javascript.info/class
- adam2님의 블로그 : https://velog.io/@adam2/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Prototype-%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC반응형'Front-End(Web) > Javascript' 카테고리의 다른 글
[Javascript] 2차원 배열 만들기(Array.from()) (0) 2021.01.03 [Javascript] Iteration Protocol (0) 2020.12.17 [Javascript] 제어문 - 반복문 (0) 2020.11.29 [Javascript] 제어문 - 조건문 (0) 2020.11.29 [Javascript] 변수(Variable) & 자료형(Type) (0) 2020.11.24