게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌6 - ECMAScript - 8년 전 등록 / 일 년 전 수정

ES2015(ES6) Class(클래스)

 안녕하세요. 이번 시간에는 클래스(class)에 대해 알아보겠습니다.

그 동안 자바스크립트에 클래스가 없었습니다. 그래서 다른 언어를 하셨던 분들은 자바스크립트의 객체에 대해 헷갈려했습니다. 하지만 이제 자바스크립트도 클래스가 있습니다! (하지만 내부적으로는 그대로 프로토타입을 따릅니다)

var Human = function(type) {
  this.type = type || 'human';
};
 
Human.isHuman = function(human) {
  return human instanceof Human;
}
 
Human.prototype.breathe = function() {
  alert('h-a-a-a-m');
};

var Zero = function(type, firstName, lastName) {
  Human.apply(this, arguments);
  this.firstName = firstName;
  this.lastName = lastName;
};

Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero; // 상속하는 부분
Zero.prototype.sayName = function() {
  alert(this.firstName + ' ' + this.lastName);
};
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero); // true

간단히 보면 Human 객체를 Zero 객체가 상속받고 있습니다. Human 생성자에는 isHuman이라는 static 메소드도 있네요. breathe는 모든 Human 객체가 받는 메소드이고요. ES6에서는 놀랍게 바뀝니다.

class Human {
  constructor(type = 'human') {
    this.type = type;
  }

  static isHuman(human) {
    return human instanceof Human;
  }

  breathe() {
    alert('h-a-a-a-m');
  }
}

class Zero extends Human {
  constructor(type, firstName, lastName) {
    super(type);
    this.firstName = firstName;
    this.lastName = lastName;
  }

  sayName() {
    super.breathe();
    alert(`${this.firstName} ${this.lastName}`);
  }
}

const newZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(newZero); // true

혼잡했던 생성자와 상속 코드가 깔끔해졌습니다. 물론 새로운 기능이 추가된 것은 아니지만 눈이 즐거워졌죠. 실수할 일도 줄어들고요. 실제로 이렇게 클래스로 만들어둔 것은 new를 붙이지 않으면 에러가 발생합니다. 다들 생성자에 new를 붙이지 않아서 window를 수정했던 경험이 있으실 겁니다. 이제는 그럴 일이 없습니다. 원천 차단되었거든요.

이전에 function Object() {}로 만들던 생성자 객체를 이제 class로 만들 수 있습니다. 그리고 복잡했던 상속을 class 이름 extends 부모 {}로 간단하게 처리할 수 있게 되었죠.

constructor 함수는 객체가 생성되었을 때 실행되는 함수입니다. constructor의 매개변수들은 new Zero(인자) 객체로 호출할 때 사용하는 인자들을 처리하고 있습니다. super은 아래에서 설명드리겠습니다.

객체의 prototype에 정의했던 메소드들도 이제 class 안에 넣으면 됩니다. 자연스럽죠?

Human.isHuman같은 객체의 static 메소드도 간명하게 표시할 수 있게 되었습니다. static 이름() {} 처럼 앞에 static만 붙여주면 됩니다.

주목할 점은 super입니다. 부모 객체에 접근하는 방법인데요. constructor 안과 sayName 함수 안에서 두 번 발견할 수 있습니다. constructor 안의 super은 부모의 생성자에 type을 전달하는 역할을 합니다. 부모 객체에 없는 firstName과 lastName은 따로 처리해주어야 합니다.

sayName 안의 super 역시 부모 객체에 접근하여 메소드를 호출하는 겁니다. 부모 객체의 메소드를 재사용하고 싶을 때 주로 사용합니다. 위의 예시에서는 newZero.sayName()할 경우 Human.prototype.breathe()가 호출된 후 alert가 발생합니다.

참고로 class의 body는 strict 모드가 기본 적용됩니다. 아래의 경우 window가 나와야할 것 같지만, undefined가 나옵니다. say 메서드 내부는 strict 모드가 적용되기 때문입니다. 애초에 왜 window랑 undefined가 나오는지 이해가 안 된다면 this 강좌 보고 오셔야 합니다.

class obj {
  say() {
    console.log(this);
  }
}
obj2 = new obj();
obj3 = obj2.say;
obj3();

다음 시간에는 객체 해체에 대해 알아보겠습니다. 객체를 해체한다니, 뭔가 있을거 같죠?

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

7개의 댓글이 있습니다.
3년 전
그럼 클래스로 인해서 기존에 프로토타입으로 상속하던 방식은 거의 사용하지 않게 된 건가요?
그렇지 않다면 클래스의 장점을 이길만한 프로토타입 방식의 상속이 장점이 있을까요?
3년 전
네 일반적인 경우 클래스만 써도 됩니다. 다만 클래스 내부는 프로토타입으로 동작하므로 내부 속성을 변경하고 싶으면 프로토타입을 쓰는 경우가 많습니다. 특히 남의 클래스의 내부 속성을 변경하려면요.
6년 전
var Zero = function(type, firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
super 역할을 하는 부분이 없어서 oldZero.type 이 undefined 가 나옵니다.

var Zero = function(type, firstName, lastName) {
Human.apply(this, arguments);
this.firstName = firstName;
this.lastName = lastName;
};
이렇게 수정해야 할 것 같습니다.
6년 전
아, 그 부분 빼먹었네요 감사합니다~
7년 전
감사합니다 정말 잘 보고있습니다~ 에이콘사에서 내놓은 es6 설명책이랑 다르게 훅 들어오는게 체감이 되네요 너무 알기쉽게 요점만 써놓으셨어요
7년 전
감사합니다!
7년 전
onstructor가 객체가 생성되었을 때 하는 행동입니다. constructor의 매개변수들은 new Zero(인자) 객체로 호출할 때 사용하는 인자들을 처리하는 부분입니다. super은 아래에서 설명드리겠습니다.


안녕하세요 포스팅 너무 잘 보고 있습니다. 위의 내용이 많이 헷갈리네요 더불어 실제로 다음의 코드는 값을 대입하는 것이지 아무것도 안한다는 생각이 듭니다 맞나요?.

class Human {
constructor(type = 'human') {
this.type = type;
}
7년 전
질문이 정확히 이해가 가지 않습니다만 다시 설명드리면 new가 실행되었을 때 constructor 부분이 인자로 넣어준 type을 사용하여 실행됩니다. this는 class 자신을 가리키고 있기 때문에 this.type은 객체의 type 속성이 되고, 인자로 넣어준 type이 저기 대입되는 것이죠. type 값을 인자로 넣어주지 않으면 기본값으로 설정된 'human'이 대입됩니다.
7년 전
ZeroCho님 답변 감사합니다. ES6 문법이 익숙하지 않아 학습하는데 부족함이 있었네요 이제 이해를 하였습니다. 좋은 글 잘 보고 있습니다 감사합니다!.
7년 전
안녕하세요 현영님.
맨처음 코드
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero); // true \u003c\u003c 이부분이 현재 false인데

상속하는 부분에서 아래와 같이 수정하면 주석에서 처럼 true로 나올 것 같습니다.
as-is
Zero.prototype = Object.create(Human);
to-be
Zero.prototype = Object.create(Human.prototype);
7년 전
prototype이 빠져있었네요;; 모르고 있었습니다. 감사합니다.
7년 전
안녕하세요 항상잘보고있습니다ㅎ
에러나오타는아니지만ㅎ
this.firstNane =firstName
this.lastName = lastName은 어떨까해서 올려봤습니다ㅎ항상감사합니다
7년 전
오타가 맞네요 덜덜덜 ㅠㅠ
8년 전
부모에 sayName이 없는데 super.sayName()호출이 가능한가요?
8년 전
안 됩니다. 위의 코드는 그냥 예시를 위해 만들어둔 코드입니다. 다시 보니 혼란의 여지가 있어 수정해보겠습니다! 감사합니다.