JavaScript Class

곽태민·2023년 3월 24일
0

TIL

목록 보기
51/63

Class

개발을 하면서 Class에 대한 개념을 겉핥기 식으로만 알고 개발을하니 스스로의 문제점들을 발견했다.

Constructor가 뭐고 Class를 대체 왜 사용하는지 이런 것들이 궁금해서 예전에 정리했던 것들을 잊은 채 아무것도 몰랐던 그때로 돌아가 한번 다시 알아보려고 한다.

JavaScript ES6ClassJava와 비슷하게 객체 지향적으로 표현하기 위해서 추가가 되었다. ES5이전에는 Class가 없었지만 ES5에도 Prototype 문법으로 Class를 비슷하게 구현해왔다.

하지만 ES6로 넘어오면서 Java의 Class와 비슷한 구조를 갖게 되었다. 비슷한 구조를 갖게 되었을 뿐 내부적으로는 Prototype 방식으로 작동이 된다.

그럼 Prototype 방식과 Class 방식의 차이를 알아보기 위해서 간단하게 보려고 한다.

// Prototype

// 생성자
function Person({ name, age }) {
	this.name = name;
	this.age = age;
}

Person.prototype.introduce = function() {
	return `Hello, My name is ${this.name}.`;
}

const person = new Person({ name: "Jack", age: 25 });
console.log(person.introduce());
// Class

class Person {
	constructor({name, age}) {
		this.name = name;
		this.age = age;
	}

	introduce() {
		return `Hello, My name is ${this.name}.`; 
	}
}

const person = new Person({ name: "Jack", age: 25 });
console.log(person.introduce());

PrototypeClass는 같은 결과를 출력한다. 문법의 생김새는 다르지만 로직은 같은 구조로 동작을한다.


Class 문법

Class 선언

constructorinstance를 생성하며 class field를 초기화하기 위한 특수 method다.

constructorclass 안에 한 개만 존재할 수 있으며, 한 개 이상일 경우 Syntax Error가 발생한다.

classfieldconstructor 반드시 내부에서 선언과 초기화가 이루어진다.

constructor 내부에 선언한 class fieldclass가 생성할 instancebinding이 된다.

class person {
	height = 180; // instance 변수 선언

	// constructor의 이름은 변경 불가
	// this는 class가 생성할 instance를 나타냄
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
}

const person = new Person("Jack", 25);
console.log(person.name); // Jack
console.log(person.age); // 25
console.log(person.height); // 180

다른 언어의 Class와는 다르게 JavaScriptClass에서는 Instance 변수를 반드시 지정하지 않고 Constructor를 통해서 this.변수로 자동 생성을 할 수 있다.

Class Method 정의

Class의 Method 정의는 객체 리터럴에서 사용하던 방법과 비슷하게 사용한다.

class Calculator {
	add(x, y) {
		return x + y;
	}
	subtract(x, y) {
		return x - y;
	}
}

const calc = new Calculator();
calc.add(1, 1); // 2

객체 리터럴과 비슷하므로 임의의 표현식을 대괄호안에 method 이름을 지정할 수 있다.

const method = "introduce";

class Person {
	constructor({ name, age }) {
		this.name = name;
		this.age = age;
	}

	[method]() {
		return `Hello, My name is ${this.name}.`;
	}
}

console.log(new Person({ name: "Jack", age: 25 }).introduce());

정적 method (static)

정적 methodclassinstance가 아닌 class 이름으로 곧바로 호출하는 method다.

static keyword를 method 이름 앞에 붙여주면 이 method는 정적 method가 된다.

예시로 랜덤값을 얻기 위할 떄 Math.random()을 사용하듯 new Math()없이 곧바로 class이름에 method이름을 호출해서 사용하는 것이 random methodstatic으로 되어 있어서다.

class Person {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
	static static_name - "STATIC";

	getName() {
		return this.name;
	}
	static static_getName() {
		return this.static_name;
	}
}

const person = new Person({ name: "ian", age: 25 })'
person.getName(); // ian
Person.static_getName(); // STATIC

Class 상속

Class 상속을 통해서 하나의 class 기능을 다른 class에서 재사용을 할 수 있다.

extends

extends는 class를 다른 class의 하위 class로 만들기 위해 사용된다.

class Parent {

}

class Child extends Parent {

}

위 코드를 보면 extends를 이용해서 Child class가 Parent class를 상속했다.

이러한 관계를 “부모 class - 자식 class” or ‘’superclass - subclass” 관계라고 한다.

따라서 어떤 class A가 다른 class B를 상속받게 된다면 아래와 같은 일들이 발생한다.

  1. subclass A를 통해서 superclass B의 정적 method와 정적 property를 사용할 수 있다.
  2. superclass Binstance methodinstance propertysubclass Ainstance에서 사용할 수 있다.
class Parent {
	static staticProp = "staticprop";
	static staticMethod() {
		return "This is static method";
	}

	instanceProp = "intanceprop";
	instaceMethod() {
		return "This is instance method";
	}
}

class Child extends Parent {}

// 상속 시 Superclass static 요소 사용 가능
console.log(Child.staticProp);
console.log(Child.staticMethod());

// 상속 시 Superclass의 instance를 사용 가능
const child = new Child();
console.log(child.instanceProp);
console.log(child.instanceMethod());

super

super의 동작 방식은 아래와 같다.

  1. 생성자 내부에서 super를 함수처럼 호출하게되면 superclass의 생성자가 호출
  2. 정적 method 내부에서 super.prop과 같이 써서 superclass의 prop 정석 속성에 접근할 수 있다.
  3. instance method 내부에서는 super.prop과 같이 써서 superclass prop instance 속성에 접근할 수 있다.
super(); // 부모 생성자
super.methodName // 접근

------------------------------------------------------------------------

class Person {
	constructor(name, first, second) {
		this.name = name;
		this.first = first;
		this.second = second;
	}

	sum() {
		return (this.first + this.second);
	}
}

class Person2 extends Person {

	// Override Person
	constructor(name, first, second, third) {
		// 부모 생성자를 가져와 편하게 사용
		super(name, first, second);
		this.third = third;
	}

	sum() {
		// 부모 method를 가져와 사용
		// 오버로딩 method에서 온전한 부모 method를 사용하고 싶을 떄
		return super.sum() + this.third;
	}
}

const kim = new Person2('kim', 10, 20, 30);
console.log(kim.sum) // 60

Private class 변수

Javascript class의 모든 methodPublic으로 지정되었는데 ES2021부터는 methodfield명 앞에 “#”을 붙이면 Private method와 field 정의가 가능해졌다. (private으로도 사용가능)

class myClass {
	// private 변수
	#num = 100;

	// private method
	#privateMethod() {
		// Private 변수 호출
		console.log(this.#num);
	}

	publicMethod() {
		// Private Method 호출
		this.#privateMethod();
	}
}

const newClass = new myClass();
newClass.publicMethod(); // 100
profile
Node.js 백엔드 개발자입니다!

0개의 댓글