본문 바로가기
안드로이드 웹앱 콘테츠 개발자 양성(국비지원)/HTML+Java script

ECMA script 2015(ES6) class (멤버 변수,메소드 사용 및 구조분해할당)

by 차누감 2019. 12. 20.

① 새로운 변수 선언 키워드 : let, const
② class 키워드 ,extends
③ 화살표 함수 (Arrow Function)
④ module 문법 : import, export

 

<최종 화면> - class를 만들고, 참조변수로 참조, 멤버 변수,함수 사용 및 구조분해 할당을 알아본다.


다른 언어에서 사용 되는 class의 개념이 기존 JS에 없었지만, ES6에 개념이 등장하였다.

class에 대해 알아보자.

class에 멤버 변수는 반드시 생성자에 만들어야 한다. (this 사용)

멤버 변수가 잘 나온다.

this가 아닌 let으로 선언한 gender는 어떻게 될까?

결과 화면을 보면 undefined가 나온다. 이것은 let gender가 아닌 JS에서는 변수가 없이 사용을 하면 새로 만든다.

결국 person.gender라고 사용을 하면 새로 멤버 변수 gender를 만들고 화면에 표시된 것이다. (그래서 값이 undefined.)

클래스의 멤버 변수를 this로 하듯이, 멤버 메소드도 형식이 있다.

바로 메소드명을 사용하여 만든다. 

스크립트문을 새로 사용해도 class는 같은 파일 안에서 인식한다. 

위 Person클래스로 참조변수를 만들어서 멤버변수의 값은 고정된 값이다. 이를 변경하기 위해서는 

person2.name="aaa"; 이런식으로 일일히 변경해야한다. 

객체를 생성할 때 멤버 변수에 값을 전달하자. (생성자 함수 파라미터 사용)

만약에 생성자에 파라미터를 실수로 입력 안했다면? 변수 선언을하고 값을 전달 안한 것과 같다. (undefined)

JS 함수의 오버로딩이 안되므로

아래 코드와 같이 값이 없을때는 정해진 값으로, 전달하며 전달한 값으로 나오게 할 수 있다. (매개 변수에 default 값)

 

혹시 일반 메소드는 함수의 오버로딩이 가능한가? 결론은 안된다.

출력된 결과를 확인해 보면, output()메소드가 2개 만들었지만.. 마지막 output(n)메소드가 호출이 된다. (매개변수와 상관없이..)

메소드의 리턴은 특별히 다를게 없다.

클래스의 멤버 함수의 사용 형식은 여러 가지가 있다.

show(){ 내용 }  /  show=function(){ 내용 }    /  show=aaa;   function aaa(){ 내용 }

class를 알아봤으니, 상속에 대해서도 알아보자.

우선 새로운 Human 클래스를 만들자.

이제 Human class를 상속받은 Student class를 만들자.

Student class안에 아무 것도 안써도 Human class를 상속 받았기 때문에 show()메소드 사용이 가능하다.

(Human의 멤버 변수,메소드들을 사용 가능)

위 사진처럼 show() 호출해도 값이 없어서 name, age가 undefined가 된다.

그래서 Student도 생성자 메소드를 만들자.

생성자 메소드를 만들 시, 상속을 받았다면? 생성자 메소드에 부모 생성자를 호출하는 코드가 있어야한다.( super(); )

Student는 멤버 변수로 major가 있지만, show에는 major를 표시하는 코드가 없다.

이때 부모로 부터 받은 메소드를 재정의하는 함수의 오버라이딩을 하자.

static 정적 키워드에서도 알아보자. 

First 클래스를 만들고 멤버 메소드로 show() 정의한다. 단, 메소드를 static으로

지금까지 클래스의 멤버 메소드를 사용하려면 객체를 생성하고 참조변수.show(); 이런 식으로 호출했다.

하지만 static으로 정의했다면 클래스명.show();로 바로 접근 가능하다.

변수에도 static 사용이 가능하다.

단, 멤버 변수는 this 키워드를 사용했는데.. this키워드를 사용하지 않고 static을 사용해야한다.

또한 생성자 안에서 static 키워드는 사용할 수 없다.

jS중 하나의 멤버 변수를 나중에 선언도 가능하다.

클래스 내의 멤버 변수로 만들지 않고, 나중에 없는 변수를 사용할 시 그때 만들어진다.

위 사진처럼 주의점은 객체를 만들고 참조 변수로 name을 접근하려 했다. (static name="kim";)

하지만 객체를 만들고 참조변수 k로 k.name을 할 시 새로운 멤버 변수name이 만들어지는 것이다.

객체를 참조하는 참조 변수로는 static 변수 접근 못함.

만찬가지로 객체를 참조하는 변수로 static 메소드도 사용할 수 없다.

static 변수, 메소드는 클래스 명으로 접근!!

이제 구조 분해 할당에 대해 알아보자.

우선 새로운 Nice 클래스를 만들고 멤버변수를 사용하자.

지금까지는 멤버 변수를 사용하기 위해 객체를 만들고, 객체를 참조하는 참조변수.멤벼번수; <-이런식으로 사용

불편하다. 좀더 짧게 사용하고 싶다면 구조 분해 할당을 사용하자.

결론은 아래 사진과 같이 객체까지는 똑같이 만들고

nice.name을 미리 선언하여 name으로만 사용하는 그런 것이다.

{}중괄호 안에 여러개 사용 가능하다.

메소드의 매개변수로 객체를 전달하고 {}중괄호(구조 분해 할당)를 이용해서 멤버 변수 사용 가능하다.

구조분해 할당은 멤버 변수와 {}안의 변수 이름이 다르면 안된다.

아래 예제는 똑같이 사용해서 된다.

만약 구조분해를 하는데, 멤버 변수가 많다면? {}중괄호 안에 얼마나 많은 변수를 써야할까...

그래서 ...rest라는 정해진 키워드를 사용하자. 그러면 나머지 멤버 변수를 대변한다.

사용할때는 rest.변수명으로 사용 가능하다.


<복붙용 코드>

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        //객체를 생성하는 새로운 문법 : class키워드 등장
 
        // 1. 클래스 선언 [객체를 만드는 것 아님!!]
        class Person{
            // 기존에 하던 생각으로 멤버변수 모두 에러..
            // 멤버변수는 반드시 생성자(constructor)에서 만들어야 함.
            // 생성자 함수
            constructor(){
                this.name= "sam"//멤버변수 선언 및 초기화
                this.age= 20//멤버변수 선언 및 초기화
 
                let gender="male"// 이건 멤버변수가 아니라 생성자 함수의 지역 변수임.
            }
 
            // 멤버 메소드
            // function show(){} //에러!!
            // 메소드를 만들때는 function이라는 키워드를 생략해야만 함.
            show(){
                document.write("name : "+this.name+", "+"age: "+this.age+"<br>"); //JS에서는 this 키워드 꼭 있어야됨
            }
        }//Person class..
 
        //객체 생성
        let person=new Person();
        person.show();
        document.write('name: '+ person.name+"<br>");
        document.write('age: '+ person.age+"<br>");
        document.write('gender: '+ person.gender+"<br>"); //undefined.. let gender가 아닌 새로운 멤버변수 gender를 만들고 출력한 것이다.
 
    </script>
 
    <script>
        // 같은 .html문서 안에만 있으면 어디서든 class를 인식함
        let person2= new Person();
        person2.show();
 
        // 객체를 생성하면서 값을 전달할 수 있음. 생성자 함수 파라미터..
        class Member{
            // constructor(id, pw){
            //     this.id=id;
            //     this.pw=pw;
            // }
            // 파라미터를 받지 않는 또 다른 생성자함수 (overloading)
            // JS는 생성자 함수를 오버로딩할 수 없음. 문법적으로 막았음.!!
            // 즉, constructor()는 class에 1개만 사용가능함.
            // constructor(){
            //     this.id="noname";
            //     this.pw="0000";
            // }
 
            // 생성자 함수에 파라미터 전달했을 때는 전달한 값으로..
            //안했을 때는 기본값이 있도록...
            constructor(id="noname", pw="0000"){ //매개변수의 default값[c++문법]
                this.id=id;
                this.pw=pw;
            }
 
            // 일반 메소드도 오버로딩이 안될것인가? - 안됨! 함수 덮어써짐
            output(){
                document.write('no data<br>');
            }
            // 함수 덮어쓰기!!
            output(n){
                document.write('data'+ n +'<br>');
            }
 
            // 함수의 리턴은 특별할게 없음
            add(a,b){
                return a+b;
            }
            // show(){
            //     document.write("ID : "+this.id+", "+"PW : "+this.pw+"<br>");
            // }
 
            // // 메소드를 만들때 익명함수로 만들어도 됨!!
            // show=function(){
            //     document.write(this.id+", "+this.pw+"<br>");
            // }
 
            // 함수는 변수에 대입이 가능하죠..
            // 이런식으로 메소드를 만들 수 있음.
            show=aaa;
 
        }//Member class..
 
        let member= new Member("mrhi""1234");
        member.show();
 
        function aaa() {
            document.write(this.id+", "+this.pw+"<br>");
        }
 
        let member2= new Member("androdi""4567");
        member2.show();
 
        let member3= new Member(); //전달안하면.. 파라미터의 기본 값 undefined
        member3.show();
 
        //생성자 함수에 값을 전달하지 않았을 때를 위한 overloading된 생성자 함수
 
        member3.output();
        member3.output(50);
 
        let num= member3.add(5,3);
        document.write(num+"<br>");
    </script>
 
    <script>
         document.write(num+"<hr>");
        // 상속
        class Human{
            constructor(name, age){
                this.name= name;
                this.age= age;
            }
            show(){
                document.write("name: "+this.name+", age: "+this.age+"<br>");
            }
        }
 
        let h= new Human("sam",20);
        h.show();
 
        // 상속 받기
        class Student extends Human{
            constructor(name, age, major){
                // ERROR- 상속 받았을 때 부모생성자를 호출하는 코드를 명시적으로 작성하지 않으면 ERROR
                super(name,age);
                this.major=major;
            }
 
            // 부모의 show()메소드를 오버라이딩(overriding)
            show(){
                super.show();
                document.write("major: "+this.major+"<br>");
            }
 
        }
        let stu= new Student("robin",25,"javascript");
        stu.show();
    </script>
 
    <script>
          document.write('<hr>');
        // 정적 키워드 : static
        class First{
            static show(){
                document.write('static method....~~~~~~<br>');
            }
        }
        //객체 생성 없이 메소드 사용
        First.show();
 
        // static 변수
        class Second{
            constructor(){
                //static 키워드는 메소드 안에서 사용 불가!!
            }
            // 메소드 밖에
            static name="kim"//static 사용할 때는 this.키워드 사용하면 안됨!!
        }
        document.write("name: "+Second.name+"<br>");
 
        // 정적 멤버 변수도 나중에 추가할 수 있음.
        Second.num=50;
        document.write("num: "+ Second.num+"<br>");
 
        // 자바와 다른 점.. 객체로 만들어서 참조 변수로 static 멤버 사용 불가
        let k= new Second();
        document.write("name: "+k.name+"<br>"); //k객체안에 일반 멤버변수 name을 추가한 것임.. undefined
    
        // static 메소드는 없는 것을 호출하면 에러
        let f= new First();
        //f.show(); //일반 메소드 show()를 호출한 것임.. 이런 메소드 없음. error
        //static은 클래스로 접근, 객체로 하면 안된다.
       
    </script>
    
    <script>
    document.write('<hr>');
 
    // 구조 분해 할당
    class Nice{
        constructor(){
            this.name="kim";
            this.age=20;
            this.address="SEOUL";
        }
    }
 
    let nice= new Nice();
    document.write("name: "+nice.name+"<br>");
    document.write("age: "+nice.age+"<br>");
    document.write("address: "+nice.address+"<br>");
 
    // 객체의 특정 멤버를 뽑아서 일반 변수처럼 사용하는 문법[구조 분해 할당]
    const {name, age}= nice; //nice객체에서 name변수만 뽑아라!!
    document.write('name : '+name + "<br>");
    document.write('age : '+age + "<br>");
 
    // 함수의 매개변수로 객체를 전달하고 함수안에서는 구조분해할당으로
    // 그 객체의 멤버중 일부를 일반변수처럼 사용할 수도 있음
    eee(nice);
 
    function eee( {address} ) { //구조 분해 할당으로 파라미터 받음
        document.write(address+"<br>");   
    }
 
    // 구조분해 할당 할때 멤버변수의 이름과 다르면 안됨
    const {address}=nice;
    document.write("address: "+address+"<br>"); 
 
     //구조분해 할당의 특이한 문법
    //특정멤버를 제외한 나머지들을 하나의 객체로.....할당
    class Hello{
            constructor(){
                this.aaaa= 10;
                this.bbbb= 20;
                this.cccc= 30;
                this.dddd= 40;
            }
        }
 
        let hello= new Hello();
        document.write("aaaa : "+ aaaa +"<br>");
        document.write("bbbb : "+ rest.bbbb +"<br>");
        document.write("cccc : "+ rest.cccc +"<br>");
        document.write("dddd : "+ rest.dddd +"<br>");
 
            
    </script>
 
</body>
</html>
 

댓글