ES2015 - Class와 생성자
1. Class 선언
* ES5에서는 함수로 클래스 정의함 -> 한눈에 class인지 알아볼 수 없는 애매한 방법으로 정의함
var User = (function() {
function User(name){
this.name = name
}
User.prototype.sayHello = function(){
console.log(`sayHello...&{this.name}`)
}
return User
})()
이전과 달리 웹 애플리케이션으로 진화하면서 대부분 클래스로 개발하게 됨
*ES5에서는 함수로 클래스 정의함
var obj1 = new User('kkang')
var obj2 = new User('kim')
obj1.sayHello() //sayHello...kkang
obj2.sayHello() //sayHello...kim
**ES2015에서는 class 예약어로 클래스 선언함
class User{
constructor(name){
this.name=name
}
sayHello(){
console.log(`sayHello...${this.name}`)
}
}
딱 봐도 클래스라는것을 알 수 있음.
constructor라는 예약어로 선언된 함수 => 누가봐도 생성자라는것을 알 수 있음.
var obj1 = new User('kkang')
var obj2 = new User('kim')
obj1.sayHello() //sayHello...kkang
obj2.sayHello() //sayHello...kim
2. 생성자
:클래스에 들어가는 가장 중요한 구성요소
* 객체 생성 시점에 호출되는 함수
* constructor 이름으로 선언되는 함수
* 하나의 클래스 내에 하나의 constructor 함수만 선언 가능함
-> 몇 언어들은 생성자의 매개변수를 다르게 해서 여러 생성자를 선언할 수 있게 함
=> 오버로딩 지원 불가능함
생성자의 오버로딩
생성자를 여러개 정의해서 제공하는 것
생성자 오버로딩이 지원 안되면 불편하지 않나? => 함수의 매개변수의 디폴트 아규먼트가 선언이 되면 오버로딩이라는게 의미가 없어짐. 이전에 오버로딩을 지원해줬던 언어들은 함수 매개변수의 디폴트 아규먼트 선언을 지원을 안했던 것. 즉 옵셔널을 지원하지 않다보니까 매개변수가 두개면 무조건 매개변수 두개 줘야 하고 세개면 무조건 세개 줘야 하고.. 그랬는데 옵셔널을 지원하거나 디폴트 아규먼트를 지원하면 함수가 하나여도 호출할때 매개변수를 하나 줄 수도 있고, 두개 줄 수도 있고, 세개 줄 수도 있음.
그럼 함수는 하나이지만 마치 함수가 세개 선언되어 있는 것처럼 이용할 수 있다는 것.
-> 자바스크립트에서도 디폴트 아규먼트 선언해서 옵셔널이 가능하니까 함수가 여러개 나올 필요가 없다. 그래서 생성자도 하나만 선언이 가능하다.
옵셔널이나 default argument를 지원하면 함수 하나에 매개변수 여러 개 줄 수 있음
- 생략 가능하며 생략하면 매개변수 없는 constructor가 자동 추가됨
class User{}
class User1{
constrctor(){}
}
클래스 내에 생성자가 없는 클래스는 존재할 수 없다-> 이렇게 선언한 클래스는 이 안에 constructor 함수가 없으니까 생성자가 없는거 아니냐? -> 아님.
개발자가 클래스를 만들 때 명시적으로 생성자를 선언하지 않았다면 디폴트 constructor가 추가됨.
Default 생성자
:매개변수가 없는 생성자
class User2{
constructor(name){} //원하면 이런식으로 매개변수를 추가해주면 됨
}
var obj1 = new User()
var obj2 = new User1()
var obj3 = new User2('kkang')
3. 상속
*extends예약어로 상속 관계 명시
*super 예약어로 상위 클래스의 생성자, 멤버 지칭
class Shape{
constructor(id, x, y) {
}
}
class Rectangle extends Shape{
constructor(id, x, y, width, height) {
super(id, x, y)
}
}
var obj = new Rectangle(1, 0, 0, 100, 100)
하나의 클래스가 있고, 이 클래스를 상속받아서 다른 클래스를 만들고 싶으면
extends 예약어로 상속받고자 하는 클래스를 명시해서 정의하면 됨.
상속을 받으면 상위 클래스에 선언되어 있는 멤버들을 마치 내것처럼 쓴다 라는 것
그런데 경우에 따라서 다시 하위 클래스에서 상위 클래스에 있는 멤버들을 접근하거나 할 때는 super 예약어를 써주면 됨.
1. Property
-클래스의 멤버 변수
-클래스의 선언영역에서 선언
- 클래스 내에서 멤버 변수 접근은 this 예약어를 이용함
class User{
name
address='seoul'
constructor(arg1, arg2){
this.name = arg1
}
sayHello(){
console.log(`${this.name}, ${this.address}`) //hello, seoul
}
}
name과 address라는 두개의 property가 선언되어 있음
하나의 생성자에 두개의 매개변수가 있음. -> 이 매개변수는 생성자 내에서만 쓰는 로컬 variable이 됨
이 로컬 variable의 값을 클래스의 멤버 variable인 name에다가 대입하겠다=> this 예약어로 이용
자신의 property클래스의 멤버변수의 로그를 찍으려면 this예약어로 접근
- 클래서 선언영역이 아닌 생성자 내부 혹은 함수 내부에서도 클래스 멤버 변수 선언이 가능함
class User{
constructor(arg1, arg2){
this.name = arg1
this.email = arg2
}
someFun(){
this.age = 30
}
sayHello(){
console.log(`${this.name}, ${this.email}, ${this.age}`)
//hello, a@a.com, 30
}
}
일반적으로 클래스의 멤버 변수들은 클래스 선언 영역에 위치 시킨다
그런데 함수 내에서도 선언할 수 있다.
위 코드를 보면 arg1, arg2에 매개변수가 들어왔는데 이 값을 this.name에 대입하려고 하고 있음. 이 클래스의 멤버 변수를 지칭하는 것인데 클래스 영역에는 name변수가 선언되어 있지 않다. ->전혀 문제 없음!
클래스 영역에 멤버변수가 선언되어 있지 않아도 생성자나 함수 내에서 this.name과 같이 바로 선언하고 사용 가능
2. Getter/Setter
- getter, setter는 get과 set 예약어로 선언되는 함수
- 외부에서는 property로 이용
class Product{
constructor(arg){
this._name = arg
}
get name() { return this._name}
set name(arg) { this._name = arg}
get price() { return this._price}
set price(arg) { return this._price}
}
클래스 내부에서는 함수이지만 외부에서는 property로 이용하기 위해 예약어로 getter과 setter을 만듦
//외부에서 이용할 때
var prod = new Product('book1')
prod.name = 'book2'
prod.price = 200
console.log(`${prod.name}, ${prod.price}`)
예약어로 만든 함수를 외부에서는 변수처럼 사용할 수 있음
위 코드에서 name이라는 함수에 값을 대입했음 -> 내부적으로 set함수가 콜 됨
밑에서 name이라는 property의 값을 얻고 있음 -> 내부적으로 get함수가 콜 됨
데이터를 그냥 받아들여서 값을 변경시키거나 자신의 데이터를 그냥 넘겨야 되는 함수 정도
이런 정도는 get, set을 붙여서 외부에서 그냥 property를 사용할 수 있게끔 하는게 좋음
- get, set이 선언되어 있는 함수를 외부에서 함수로 이용할 수는 없음
class Product {
get price() { return this._price}
set price(arg) {this._price = arg}
get code(arg) {return this._code} //error
set code(arg1, arg2) {this._code = arg1} //error
}
var prod = new Product('book1')
prod.price('100') //error
prod.price = 200
3. static 함수
-static 예약어로 추가되는 함수
-클래스 명으로 접근해야 함(객체로 접근 불가)
- static 함수에서 Object member 접근하면 Undefined임
class User2 {
data = 10
static fun1() {
console.log(`data : ${this.data}`) //undefined
}
fun2() {
console.log(`data : ${this.data}`)
}
}
data처럼 static 이 붙지 않은 object 멤버변수를 static이 붙은 함수에서 접근하면 undefined가 뜸.
static이 붙지 않은 함수
: 객체 생성 후 객체에 접근
1. 객체생성하지 않고 fun1함수 콜하면 문제 x
객체 생성하지 않고 클래스에 바로 접근하기 때문에 문제 없음
2. static이 붙지 않은 함수를 콜하면 error
static이 붙지 않은 함수는 객체를 생성하고 접근해 줘야 함
4. 생성된 객체로 static 함수를 콜하면 error
static함수는 객체로는 접근 할 수 없다. 클래스명으로만 접근해야 함
실습
정상적으로 값 출력
<클래스의 상속 관계 테스트>
굿