상속1. constructor, prototype

mangyun·2022년 1월 10일
0

프론트엔드

목록 보기
18/21

constructor(생성자 함수)

비슷한 object를 쉽게 생성할 수 있는 기계를 만든다고 생각하자.
1. this - 기계에서 새로 생성되는 object(intance 인스턴스이다.)
2. 기계 - object 생성기계(constructor 생성자이다.)

function 기계(name, age) { //생성자이고, 파라미터를 마음대로 넣을 수 있다.
        this.name = name; //인스턴스, 기계에서 새로 생성되는 object
        this.age = age; //위와 동일
        this.sayHi = function() {//위와 동일, 함수도 된다.
            console.log(`안녕하세요 ${this.age}${this.name}입니다.`)
        }
    }

    let 학생1 = new 기계('kim', 13); //new로 생성자 호출
    let 학생2 = new 기계('lee', 17); //위와 동일

    학생1.sayHi();//메소드호출
    학생2.sayHi();//위와 동일

prototype(유전자)

constructor(기계)를 만들면, prototype(유전자)이라는 항목이 기계 안에 몰래 생성된다.
다른언어에 없고 js에만 있지만, 옛날 문법이다.

function constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    constructor.prototype.sayHi = function() { //prototype으로 부모에 저장
        console.log(`안녕 나는 ${this.age}${this.name}이야`);
    }
    var 학생1 = new constructor('Kim', 20);
    var 학생2 = new constructor('Park', 21);
    학생1.sayHi(); //출력 동일
    학생2.sayHi(); //동일

작동원리

자바스크립트는 오브젝트에서 값을 출력할 때 우선순위로 검사한다.
(1) 학생1에 이미 gender라는 값이 있는가?
(2) 그럼 부모 유전자에 gender라는 값이 있는가?
(3) 그럼 부모의 부모 유전자에 gender라는 값이 있는가?
(4) 그럼 부모의 부모의 부모의 유전자에 .. 그게 있는가?

참고

js 내장함수 toString() 등을 쓸 수 있는 이유

var arr = [1,2,3]; // var arr = new Array(1,2,3); , 사실 부모가 Array로 존재하는 것이다.
console.log( arr.toString() ); //그래서 상속 가능

특징

  1. prototype은 constructor 함수에만 몰래 생성된다.
  2. 내 부모 유전자를 찾고 싶다면, proto를 출력해보면 된다.
function 기계(){
  this.name = 'Kim';
  this.age = 15;
}
var 학생1 = new 기계();
console.log(학생1.__proto__); // 서로같다.
console.log(기계.prototype); // 동일
3. __proto__를 직접 등록하면 object끼리 상속이 가능하다. ()
var 부모 = { name : 'Kim' };
var 자식 = {};
자식.__proto__ = 부모; //Object.getPrototypeOf(자식) = 부모; 와 같다.
console.log(자식.name);//Kim, 자식이 부모에게 직접 등록한다.

결론

prototype 상속과 constructor 상속의 차이

자식들이 값을 직접 소유하게 만들고 싶으면 constructor로 상속시키면 되고,
부모만 가지고 있고 그걸 참조해서 쓰게 만들고 싶으면 prototype으로 상속시키면 된다.
보통은 그래서 상속할 수 있는 함수같은 것들은 prototype으로 많이 만들어놓는다.

문제1. 우선순위 파악

function Parent(){
  this.name = 'Kim';
}
var a = new Parent();
a.__proto__.name = 'Park';
console.log(a.name) //Kim, a.name에 이미 Kim이 있으므로 Park은 우선순위가 밀린다.

문제2. arrow function 사용

 function Student(이름, 나이){
  this.name = 이름;
  this.age = 나이;
}

Student.prototype.sayHi = () => { //arrow function은 일반 function과 다르다.
    console.log('안녕 나는 ' + this.name + '이야'); //this가 바깥에 있는 window가 되어버린다.
  }
var 학생1 = new Student('Kim', 20);
학생1.sayHi(); //안녕 나는 이야

문제3. 모든 array에 적용할 수 있는 n 빼주는 함수

let arr = [1, 2, 3, 4, 5, 6, 3];
Array.prototype.remove = function(n) { //배열의 부모인 Array의 prototype에 함수 remove 지정
    for (let i = 0; i < this.length; i++) {
         if (this[i] === n) //모든원소 중 해당원소와 같다면,
            this.splice(i, 1); //splice로 해당 인덱스부터 1개만 제거, 따라서 해당 원소가 제거된다.
     }
}
arr.remove(3); //3만 제거
console.log(arr); //[1,2,4,5,6] 출력
profile
기억보다는 기록을 하자.

0개의 댓글