상속2. class / getter, setter

mangyun·2022년 1월 12일
0

프론트엔드

목록 보기
19/21

Object.create()

ES6의 class에 밀려난, 쉽지만 잘 안쓰이는 ES5문법이다.

var 부모 = { name : 'Kim', age : 50 };
var 자식 = Object.create(부모); //상속
자식.age  = 20;
var 손자 = Object.create(자식); //상속
console.log(손자.age); //손자의 부모인 자식의 age를 가져온다.

class

constructor, prototype을 이용한 상속기능을 보기쉽게 만들어준다.
ES6문법이고, 제일 많이 쓴다.

class 부모 {
  constructor(이름, 나이){ //파라미터를 넣을때는 constructor에 넣어야한다.
    this.name = 이름;
    this.age = 나이;
    this.sayHi(){ console.log('안녕'); } //선언방식1 - constructor안에 넣으면, 자식까지 포함해서 상속한다.
  }
  sayHello(){//선언방식2 - constructor 밖이면, 자식에서 우선순위가 밀리게 되는 prototype이 된다.
    console.log('안녕하세요');
  }
}
var 자식 = new 부모('Park');
자식.__proto__.sayHello = function() { //언뜻보면 부모.prototype과 같아보이지만, 우선순위가 더 높다.
         console.log('감사합니다');
}

자식.sayHi(); //안녕    
자식.sayHello(); //감사합니다 - 자식.__proto__.가 부모.prototype보다 우선시되는 재밌는 경우였다.

class extends / super

기존에 있던 class의 내용을 그대로 복붙해서 만들어준다.

class 할아버지 {
        constructor(name, name2) {
            this.= 'Kim'
            this.이름 = name;
            this.이름2 = name2;
        }
        sayHi() { //할아버지 prototype
            console.log('안녕 나는 할아버지');
        }
    }

class 아버지 extends 할아버지 { //할아버지를 상속한다.
        constructor(name, name2) {
            super(name, name2); //constructor 안에서 쓰면 부모 constructor이다.
            this.나이 = 50;
        }
        sayHi() { //아버지 prototype
            console.log('안녕 나는 아버지');
            super.sayHi(); //console.log('안녕 나는 할아버지'); - prototype안에서 쓰면 부모 prototype이다.
        }
    }

    let 아버지1 = new 아버지('이명윤', '이개발');
    아버지1.sayHi();//더 가까운 아버지 prototype이 먼저 실행된다.
    //안녕 나는 아버지
    //안녕 나는 할아버지

문제 1. 고양이는 .한살먹기()를 쓸 수 있고, 개는 소용없게 해보자.

class Dog {
        constructor(type, color) {
            this.type = type;
            this.color = color;
        }
        한살먹기() {
            if (this instanceof Cat) { // Cat으로부터 생성된 객체라면,
                return this.age + 1
            }
        }
    }

    class Cat extends Dog {
        constructor(type, color, age) {
            super(type, color);
            this.age = age;
        }
    }

    let cat1 = new Cat('러시안블루', 'white', 3);
    console.log(cat1.한살먹기()); //4 출력

getter / setter

얕은 의미 - 오브젝트 내의 함수들을 괄호없이 쓰게 해주는 옵션들
깊은 의미 - 데이터 무결성을 위해 원본데이터는 건드리지 않고, 함수로 간접적으로 다루기 위함

굳이 이렇게 하는 이유

  1. 매우 긴 object 안에 원하는 자료 몇개만 뽑고 싶을 때, 미리 함수를 만들어놓으면 매번 기능개발해줄 필요가 없다.
  2. 내부에 있는 name, age를 건드리지 않아, 실수를 방지할 수 있어서 안전하다.

참고

다른 언어에선 코드가 class 단위로 동작하는데, class 안에 가끔 외부로부터 보호(실수로 수정방지)하고 싶은 변수들이 있다.
그럴 때 저런 함수를 많이 만들어 사용하고, 그런 코딩스타일을 js에 그대로 적용하고 있다고 보면 된다.

get - 데이터를 뽑거나, 가져온다.
set - 데이터를 입력하거나, 수정한다.

  1. 일단 get, set을 안 쓰는 경우
var 사람 = {
  name : 'Kim',
  age : 30,
  setAge(나이){//안전장치 - 내부의 name, age를 보호해서 실수를 방지한다.
    this.age = parseInt(나이) // parseInt는 문자를 숫자로 바꿔준다.
  }
}
사람.setAge('200'); //문자를 넣었는데도 숫자 200으로 저장된다.
  1. get, set을 쓰는 경우(소괄호 쓰기 귀찮을 때)
var 사람 = {
        name: 'Kim',
        age: 30,
        get nextAge() { //getter(get이 붙은 함수) - return이 있어야 한다.
            return this.age + 1;
        }
        set setAge(나이) { //setter(set이 붙은 함수) - 파라미터가 한개 꼭 존재해야한다.
            this.age = parseInt(나이);
        }
    }
    사람.setAge = '200'; //편하게 대입한다.
    사람.nextAge; //편하게 호출한다.
  1. class에서 사용하는 get/set
    내용들은 위와 동일하다.
class 사람 {
  constructor(){
    this.name = 'Park';
    this.age = 20;
  }
  get nextAge(){
    return this.age + 1
  }
  set setAge(나이){
    this.age = 나이;
  }
}
var 사람1 = new 사람();
사람1.setAge = '200'; //편하게 대입한다.
사람1.nextAge; //편하게 호출한다.

문제 1. getter, setter를 이용한 간단한 게임기능 class

class Unit {
        constructor() { //기본 공격력과 체력
            this.공격력 = 5;
            this.체력 = 100;
        }

        get battlePoint() { //현재 공격력과 체력을 더해주기, get으로 편하게 호출
            return console.log(this.공격력 + this.체력);
        }

        set heal(n) {//현재 체력에서 n을 더해주기, set으로 편하게 호출
            this.체력 += n;
        }
}
    let unit1 = new Unit();
    unit1.battlePoint; //105
    
    unit1.heal = 50; //현재 체력에서 50을 더해준다.
    unit1.battlePoint; //155

문제2. getter, setter를 이용한 배열 저장, 출력

let data = {
        odd: [],
        even: [],

        setter함수(...숫자들) { //홀짝저장함수, 숫자들 rest기호로 배열화
            숫자들.forEach(a => { //this가 window가 아닌 위의 객체를 가리키려면, arrow function 사용
                if (a % 2 == 1) //홀수라면
                    this.odd.push(a); //odd에 추가
                else //짝수라면
                    this.even.push(a); //even에 추가
            });
        },

        getter함수() { //배열들을 합쳐서, 오름차순 정렬
            let array = [...this.odd, ...this.even]; //spread로 두 배열을 합침
            return console.log(array.sort()); //오름차순 정렬 출력
        }
    };

    data.setter함수(4, 1, 6, 3, 7, 2);
    console.log(data); //odd: [1, 3, 7] , even: [4, 6, 2]
    data.getter함수();//[1, 2, 3, 4, 6, 7]
profile
기억보다는 기록을 하자.

0개의 댓글