참고영상: 드림코딩 | 자바스크립트 기초 강의
선언한 변수들이 여기저기 동동 떠다닌다면..
규모있는 프로젝트를 만들긴.. 매우 어려웠을 듯
좀 더 연관있는 데이터들을 묶어놓은
가 종합적으로 있는 것을 클래스
※ 잠깐 알아두기
객체지향 언어
라서 이것들이 이뤄짐
클래스로, 객체로 잘 만들 수 있는 개발자가 되는 것이 👍🏻
ES6에 추가됨 (!!)
🖐🏻 아니 그럼.. 그 이전엔 어케 만들었는데?
기존에 존재하면 prototype 위에 문법만 class 추가한 것
🖐🏻 prototype..? 나중에 공부할것;
class Person{
constructor(name, age){
// fields
this.name = name
this.age = age
}
speak(){
console.log(`${this.name}`: hello)
}
}
class Person{
constructor(name, age){
// fields
this.name = name
this.age = age
}
speak(){
console.log(`${this.name}`: hello)
}
}
const kim = new Person('yangwon', 20)
console.log(kim.name, kim.age)
kim.speak()
🖐🏻 이게 왜 필요한데? 왜 쓰는건데?
class User{
constructor(firstName, lastName, age){
this.firstName = firstName
this.lastName = lastName
this.age = age
}
}
const user1 = new User('Yangwon', 'Kim', -1)
console.log(user1.age)
이러면? 나이가 -1로 출력이 된다.
-1... -1살이라는 건 말이 안된다.
즉, 누군가 데이터를 멍청하게 넣거나 이상하게 입력한다면 문제가 발생할 수 있기 때문에 getter, setter를 사용하는 것 !
class User{
constructor(firstName, lastName, age){
this.firstName = firstName
this.lastName = lastName
this.age = age
}
get age(){
return this._age
}
set age(value){
// if(value < 0){
// throw Error('age cannot be negative')
// }
this._age = value < 0 ? 0 : value
}
}
const user1 = new User('Yangwon', 'Kim', -1)
console.log(user1.age)
get age()
, set age()
안에서 age를 return할 때는 _
를 붙인다.
그렇지 않으면 에러가 남.. 바로 이렇게..
왜냐하면,
이를 방지하기 위해 getter, setter안에 쓰이는 변수를 다르게 만들어주어야 함
_
를 붙이는게 국룰인듯 ㅎ매우 최근에 추가됨
그래서 아직 개발자들이 많이 사용하지는 않는..
class Experiment{
publicField = 2
#privateField = 0
}
const experiment = new Experiment()
console.log(experiment.publicField)
console.log(experiment.privateField)
privateField는 접근할 수 없음
👉🏻 그래서 undefined라고 출력된다.
마찬가지로 매우 최근에 추가됨
class Article{
static publisher= 'YANGWON KIM'
constructor(articleNumber){
this.articleNumber = articleNumber
}
static printPublisher(){
console.log(Article.publisher)
}
}
const article1 = new Article(1)
const article2 = new Article(2)
console.log(article1.publisher)
만약 이렇게 출력문을 작성하면,
모른다고 뜬다.
지정되지 않았다고 뜬다.
왜냐하면 static
은 object에 붙어있는 것이 아니라 class에 붙어있기 때문
따라서 다음과 같이 작성해주어야 한다.
class Article{
static publisher= 'YANGWON KIM'
constructor(articleNumber){
this.articleNumber = articleNumber
}
static printPublisher(){
console.log(Article.publisher)
}
}
const article1 = new Article(1)
const article2 = new Article(2)
console.log(Article.publisher) // 클래스에 접근
클래스 이름을 이용해서 호출해야 한다.
(여담) 나중에 타입스크립트할때 많이 사용된다고 한다.
👉🏻 들어오는 데이터에 상관없이 클래스에서 사용할 수 있는 것이라면 static을 사용하는게 메모리사용에 더 효율적이다.
class Shape{
constructor(width, height, color){
this.width = width
this.height = height
this.color = color
}
draw(){
console.log(`drawing ${this.color} color of`)
}
getArea(){
return this.width = this.height
}
}
이렇게 클래스를 하나 만들었다.
헌데 만약 새로운 Rectangular라는 클래스를 만드려는데 Shape의 내용과 같은 것이 있다.
이럴 때 똑같이 복붙하지 말고 상속한다.
class Shape{
constructor(width, height, color){
this.width = width
this.height = height
this.color = color
}
draw(){
console.log(`drawing ${this.color} color of`)
}
getArea(){
return this.width = this.height
}
}
class Rectangular extends Shape{
// 이렇게만 정의해도 Shape 내 필드와 메소드 다 들어옴
}
상속: 공통된 부분을 다른 곳에서 재사용할 수 있다
필요에 따라 상속받은 함수에서 상속을 한 함수 중 필요한 것만 따로 재정의
👉🏻 overriding이라고 함
class Shape{
constructor(width, height, color){
this.width = width
this.height = height
this.color = color
}
draw(){
console.log(`drawing ${this.color} color of`)
}
getArea(){
return this.width * this.height
}
}
class Rectangular extends Shape{
// 이렇게만 정의해도 Shape 내 필드와 메소드 다 들어옴
}
class Triangle extends Shape{
getArea(){
return this.width = this.height
}
}
const triangle = new Triangle(20, 20, 'red')
triangle.getArea()
삼각형의 넓이가 20*20 으로 나오게 된다.
헌데.. 삼각형 넓이는 이렇게 구하는게 아니쟈나 ㅜㅜ
따라서 이 부분만 따로 고쳐준다.
class Shape{
constructor(width, height, color){
this.width = width
this.height = height
this.color = color
}
draw(){
console.log(`drawing ${this.color} color of`)
}
getArea(){
return this.width * this.height
}
}
class Rectangular extends Shape{
// 이렇게만 정의해도 Shape 내 필드와 메소드 다 들어옴
}
class Triangle extends Shape{
getArea(){
return (this.width * this.height)/2
}
}
const rectangular = new Rectangular(20, 20, 'blue')
rectangular.draw()
console.log(rectangular.getArea())
const triangle = new Triangle(20, 20, 'red')
triangle.draw()
console.log(triangle.getArea())
이렇게 재정의하면, 호출된 getArea()
는 더이상 Shape이 아니라 Triangle 안의 getArea()
를 호출하게 됨
만약 draw()
를 오버라이딩하긴 했는데.. 부모의 draw도 같이 부르고 싶다면?
class Shape{
constructor(width, height, color){
this.width = width
this.height = height
this.color = color
}
draw(){
console.log(`drawing ${this.color} color!`)
}
getArea(){
return this.width * this.height
}
}
class Rectangular extends Shape{
// 이렇게만 정의해도 Shape 내 필드와 메소드 다 들어옴
}
class Triangle extends Shape{
draw(){
super.draw()
console.log('🔺')
}
getArea(){
return (this.width * this.height)/2
}
}
const rectangular = new Rectangular(20, 20, 'blue')
rectangular.draw()
console.log(rectangular.getArea())
const triangle = new Triangle(20, 20, 'red')
triangle.draw()
console.log(triangle.getArea())
안에 super.draw()
를 써준다.
부모의 메소드가 호출되고, 그 다음 Triangle 내에 정의한 메소드가 호출된다.
클래스를 이용해서 만들어진 새로운 인스턴스
console.log(rectangular instanceof Rectangular);
확인해주는 것 !
console.log(rectangular instanceof Rectangular);
console.log(triangle instanceof Rectangular);
console.log(rectangular instanceof Triangle);
console.log(triangle instanceof Shape);
console.log(triangle instanceof Object);
📌 자바스크립트에서 만든 모든 클래스, 오브젝트는 Object를 상속한다.