[JS] Class

Minyoung's Conference·2022년 10월 19일
0

JavaScript

목록 보기
25/28
post-thumbnail

(서브타입/슈퍼타입 파트를 보고오시면 이해가 쉽습니다.)

class User{
	constructor(name){
		this.name = name;
	}
	sayName(){
		console.log(this.name);
	}
}

User라는 클래스에는 name이라는 프로퍼티가 있고, sayName이라는 메소드가 존재한다.

클래스를 사용하는 이유는 인스턴스를 만들기 위함이다. 인스턴스를 만들어 보자.

var me = new User("Bradley");

익숙하지 않은가? 생성자함수로 인스턴스를 만드는 것과 같다.

me.sayName(); // "Bradley"

class의 constructor는 Object의 constructor와 다르다. 클래스의 생성자 함수이다.
그래서, User의 인스턴스가 만들어질 때 자동으로 실행된다.

이 코드를, 클래스를 사용하지 않고 만들면 어떻게 될까? 

class의 constructor가 아래의 생성자 함수와 같은 역할을 한다.

function UserOld(name){
  this.name = name;
}

또한, 메서드를 추가해줄 때는 프로토타입을 이용했다.

UserOld.prototype.sayName = function(){
	console.log(this.name);
}

var user = new UserOld("Bradley")
user.sayName(); // "Bradley"

똑같이 나오는 것을 확인할 수 있다.

그렇다. 클래스는 정확히 생성자를 이용한 타입 생성과 그 결과가 일치한다.
자바스크립트만의 사용자 정의 타입 생성 방법을 다른 언어의 클래스 문법처럼 바꿔 준 것이
바로 자바스크립트 클래스이다.

class로 만든 객체를 콘솔에서 확인해보자. 

prototype이 존재하고 prototype chain까지 확인할 수 있다.

이처럼, 내부적인 동작은 동일하지만 더 보기 좋고 편리하게 개선된 문법을 
Syntactic sugar 라고 부른다. 

그렇다면, 타입 상속처럼 클래스도 상속이 가능할 것이다.
지난번에 만들었다. Sausage함수를 만들어보자.

class Sausage{
	constructor(el1, el2){
		this.inside1 = el1;
		this.inside2 = el2;
	}
	taste(){
		return this.inside1 + "와" + this.inside2 + "맛이 난다!";
	}
}

클래스가 완성되었으니, 인스턴스를 생성하자.

var classicSausage = new Sausage("닭고기", "양파");
console.log(classicSausage.taste()); // "닭고기와 양파맛이 난다!"

그렇다면, 이번엔 상속받는 클래스를 만들어보자. (extends 사용)

class FireSausage extends Sausage{}

그렇다면, Sausage의 constructor, taste메서드를 모두 사용할 수 있는 것인가? 
확인해보자.

var classicFireSausage = new FireSausage("소고기", "파");
console.log(classicFireSausage.taste()); //"소고기와 파맛이 난다!"
console.log(classicFireSausage.inside1); // 소고기
console.log(classicFireSausage.inside2); // 파
잘 동작한다!

이처럼 extends 연산자를 이용해 상위 타입의 프로퍼티를 상속받는 것이 가능하다.
(call, Object.create() 함수를 사용했던 예전 코드와 비교해보자)

그럼 이제 불맛을 내기 위해 FireSausage만의 프로퍼티와 메서드를 추가해보자!

class FireSausage extends Sausage{
	constructor(el1,el2,el3){
		this.inside3 = el3;
	}
	flavor(){
		return this.inside3 + "의 풍미도 있다!"
	}
}

추가했으니 확인해보자!

var classicFireSausage = new FireSausage("소고기", "파", "불맛");
console.log(classicFireSausage.flavor()); 

//"ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

다음과 같은 에러가 뜬다! 왜그럴까?

자식 클래스에 constructor 함수를 선언하면 부모클래스의 constructor 함수를
덮어쓰게 된다! 이를 해결하기 위해 super 메소드가 필요하다!
(super 메소드는 슈퍼타입(부모타입)의 생성자를 호출한다.)

class FireSausage extends Sausage{
	constructor(el1,el2,el3){
		super(el1,el2); // 이렇게 적용해주면 끝!
		this.inside3 = el3;
	}
	flavor(){
		return this.inside3 + "의 풍미도 있다!"
	}
}

[정리]
- 자바스크립트의 타입 생성 방법을 다른 언어와 비슷하도록 보기 쉽게 개선한 것이 바로 
	자바스크립트의 클래스이다. (원래는 prototype chain, 생성자 훔쳐오기 등으로 가능했다.)
- extends 연산자를 통해 상위 타입의 프로퍼티를 상속받는다.
- super메소드를 통해 자식클래스의 생성자 함수가 부모 클래스의 생성자 함수를 
	덮어 씌우는 것을 방지 할 수 있다.

(인프런 "코딩인터뷰를 저격하는 JS 스나이퍼 양성학교" 참고)

profile
안녕하세요, FE 개발자 김민영입니다.

0개의 댓글