Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발블로그

JS Class (2018.10.04) 본문

JS Class (2018.10.04)

학교옆메추리 2020. 5. 28. 13:49

ES6부터 자바스크립트에도 클래스개념이 도입되었다고 한다.
C나 JAVA에서 봐왔던, 내가 알던 클래스와는 조금 다르기에 정리해 보려고 한다.

클래스를 사용해보자!

// define Person class
class Person {
    constructor(name, age, email) {
        this.name = name;
        this.age = age;
        this.emailList = email ? [email] : [];
    }
    introducMyself() {
        return `I'm ${this.name}, ${this.age}years old.`;
    }
    // Getter Method
    get getEmailList() {
        return `Email : ${this.emailList.join(', ')}`;
    }
    // Setter Method
    set addMyEmail(email) {
        this.emailList.push(email)
    }
}

// create new instance
const me = new Person('kevin', 30);

me.addMyEmail = 'myEmail@gmail.com';
console.log(me.introduceMyself()); // "I'm kevin, 30."
console.log(me.getEmailList); // Email : 'myEmail@gmail.com'

class 키워드를 이용하여 클래스 객체를 생성한다. 생성자는 꼭 constructor함수를 이용해야 하며 한 클래스 내에는 생성자가 여럿일 수 없다.

introduce처럼 일반적인 메소드를 정의할 수 있다.
메소드 앞에 get, set을 붙여 getter, setter함수를 만들 수 있는데, 이에 대해 알아보자.

Get 메소드

정의하는 방법은 그냥 메소드앞에 get키워드를 붙이기만 하면 된다.
사용하는 방법이 좀 특이한데, getEmailList라는 함수가 마치 멤버변수인 것처럼 me.getEmailList로 사용하면 된다.

그렇다면 me.getEmailList()로 사용해보면 어떻게 될까? 궁금해서 한번 해봤다.

// in console
me.getEmailList()-> VM47869:1 Uncaught TypeError: me.getEmailList is not a function
at <anonymous>:1:4

위와같이 타입에러가 뜬다. 음…. 클래스 인스턴스 me를 까보자!

// in console
me-> Person {name: "kevin", age: 30, emailList: Array(1)}
age: 30
emailList: ["myEmail@gmail.com"]
name: "kevin"
getEmailList: "Email : myEmail@gmail.com"
__proto__: Object

getEmailList가 ‘멤버변수인 것처럼’이 아니라 진짜 멤버변수로 등록되어있다…!

찾아보니,
The get syntax binds an object property to a function that will be called when that property is looked up.’.
오브젝트 프로퍼티를 그 프로퍼티에 접근할때 호출되는 함수로 바인딩한다.

말이 어렵다… 솔직히 잘 이해가 안된다…
해당 오브젝트의 프로퍼티에 get 함수의 결과값으로 바인딩하고, 그 프로퍼티에 접근할 때 get함수를 내부에서 실행시켜 새로운 값을 할당해준다.’ 로 받아들였다.

Set 메소드

정의하는 방법은 get과 같지만, arguments가 최소 한 개 이상 존재해야 한다는 점에서 조금 다르다.
사용법도 같다. 객체의 프로퍼티에 값을 할당하는것처럼 사용하면 알아서 setter함수가 작동한다. 메소드처럼 사용하기 위해 함수실행 연산자 ()를 붙이게 되면 같은 오류가 난다. ( … is not a function )

Inheritance: 상속

class SuperClass { }class SubClass extends SuperClass {
  constructor() {
    super(); // 꼭 써주어야 한다!
  } 
}

Java처럼 extends 키워드를 통해 클래스 상속이 가능하다. ( ‘ , ’ 를 이용한 다중상속 안됨 )
상속받는 클래스에서는 생성자 내부에서 super()를 통해 부모클래스의 생성자를 호출할 수 있는데, 이는 선택이 아니라 필수이다.

VM73165:1 Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

자식클래스의 생성자에서 super()를 호출하지 않았을 경우에 나는 에러이다. 정확하게는 인스턴스가 생성될 때 오류가 난다. Java에서와는 달리 super()를 default로 삽입해 주지 않는 것 같다. 자식클래스에서 생성자함수를 작성하지 않는다면, 당연히 붙이지 않아도 된다.

Mix-ins

우리는 믹스인 기법을 사용하여 클래스를 확장할 수 있다. 이 믹스인을 잘 사용한다면 재사용 가능한 기능들을 효율적으로 사용할 수 있을 것이다.

 

3–8번줄에 두 개의 믹스인함수를 만들었다. 클래스를 받아와 그것을 상속하는 익명클래스를 생성하고, 기능을 추가한 뒤 뱉어준다. 10번줄에서 볼 수 있듯이 여러번 중첩해서 사용할 수도 있다.

문득 생각이 들었다. 믹스인을 더 여러번 중첩해야 한다면? ()로 중첩되어 보기에 상당히 불편해질것 같다는 생각이 들었고 그걸 해소할 수 있는 함수를 13–17줄에 만들었다. reduce함수를 이용하여 인자로 넘긴 믹스인함수들을 차례로 누적실행하여 뱉어주는 함수이다.

믹스인이라는 기법에 대해 처음 알았고, 글을 쓰기 이전에 여러 사람들이 쓴 글을 읽어보았다. 그 중에 ‘믹스인을 사용하여 다중상속을 구현할 수 있다’는 말을 몇번 봤었는데, 옳은 말인지 의문이 생겼다.

다중상속을 구현하는게 아니라 기능적으로 흉내만 내는 것이라고 생각한다. 
상속이라는게 관계가 성립할 때 이루어져야 하는 것인데 관계와는 상관없이 상속을 중첩하여 흉내내려고 하기에 그렇다. ( 위에서 sayHello와 sayBye는 관계도 없을 뿐더러 두 믹스인 순서가 뒤바뀌어도(상속관계가 뒤엎어져도) 상관없기 때문이다 )

 

 

 

 

'' 카테고리의 다른 글

JS Promise (2018.10.10)  (0) 2020.05.28
JS this (2018.10.06)  (0) 2020.05.28
JS prototype (2018.10.01)  (0) 2020.05.28
Redux (2018.06.30)  (0) 2020.05.28
Immutable.js (2018.06.26)  (0) 2020.05.28