코로 넘어져도 헤딩만 하면 그만
객체 지향 프로그래밍 1-4) 프로토타입 체인 본문
앞에서 클래스를 배웠으니, 이제 이것을 적극 활용한다.
function Person(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
};
//ES5 문법으로 작성됨, 아래는 ES6 문법으로 똑같이 작성한 결과물이다.
class Person { //class를 서서 명시해주고
constructor(first, last, age, gender, interests) { //constructor이 생겼다.
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
}
어쨌든, 위와 같이 Person이라는 객체를 만들었다.
이때 Person과 함께 자동 생성되는 것이 있는데 Person의 prototype객체이다.
이 객체에도 따로 메소드를 정의해 둬 보자.
Person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};
이제 Person을 부모로 삼는 Teacher이라는 생성자 함수를 만들어본다. 사람이지만, 동시에 선생인 생성자다.
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}
call() 함수를 사용해서 Person에서 쓴 인자들을 전부 불러오고 있다. call() 함수의 첫번째 매개변수로 this를 전달해서 현재 장소에서 실행되도록 한다. 나머지는 필요한 매개변수들을 전부 불러오면 된다.
그리고 선생만 가지는 고유한 특성을 this.subject를 사용해서 Teacher만의 고유 속성으로 추가해주었다.
+ 상속하려는 부모 생성자에 매개변수 속성이 없다면 call()에도 this만 넣어도 된다.
여기서 문제가 생긴다. 새로 생성한 Teacher 생성자는 Person.prototype에 넣어둔 메소드까진 불러오지 못했다. Person.prototype.greeting과 Teacher.prototype.greeting의 결과가 다르다는 뜻이다.
그런데 Person.prototype에 넣어둔 메소드도 Teacher에서 불러오고 싶다면?
Teacher.prototype = Object.create(Person.prototype);
Teacher.prototype.constructor = Teacher;
이때 사용하는 것이 create()이다. 새 객체를 생성하여 Teacher.prototype으로 할당하는 방식으로 이루어진다. 다만 이 경우에 Teacher.prototype의 constructor 속성이 Person()로 되어 있기 때문에 아랫줄과 같이 constructor을 수정해주는 과정이 필요하다. 이제 Teacher의 constructor은 Teacher()이 되었다.
super은 부모 객체의 함수를 호출할 때 사용된다.
- 생성자에서는 super 키워드는 하나만 사용될 것
- this가 사용되기 전에 호출될 것(super()가 먼저 호출되지 않으면 this를 쓸 때 참조 오류가 발생한다.)
__proto__ 와 prototype
자식의 .__proto__는 부모의 prototype의 '주솟값'을 갖는다. 같다고 보면 된다.
실제로! 자식.__proto__ === 부모.prototype 하면 true가 나옴.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 밥을 먹습니다`);
}
}
let Arren = new Human('애런', 27);
위와 같은 코드에서, Arren.__proto__ 는 Person.prototype과 같다는 말이다.
또... Object는 최상위 클래스라고 봐도 무방하다. Person에게도 부모 클래스인 Object가 존재하는 것이다.
이처럼 __proto__가 가리키는 대로, 하위 객체에서 상위로 존재 여부를 검색해가며 부모 역할을 하는 객체의 속성과 메소드까지 접근할 수 있는 흐름을 바로 prototype chain이라고 부른다. 해당 객체에 찾는 함수가 없을 때 상위로 점진적으로 접근하는 과정에서 프로토타입 체이닝이 일어나며, 프로토타입 체인의 최상단은 Object.prototype가 있다.
다만 MDN에는 __proto__는 더이상 사용하지 않길 바라며, 대신 Object.getPrototypeOf / Reflect.getPrototypeOf 및 Object.setPrototypeOf / Reflect.setPrototypeOf가 권장된다. 객체의 prototype 설정은 속도가 느리기 때문에 추천되지 않는다. ...고 한다. 좀더 깊이 공부해야 할 것 같다.
참고: MDN
Classes in JavaScript - Web 개발 학습하기 | MDN
OOJS에 대한 개념을 설명했으니, 이 글에서는 부모 클래스에서 자식 클래스를 상속하는 방법을 알아봅니다. 덤으로 OOJS를 구현하는데 몇 가지 참고사항도 있습니다.
developer.mozilla.org
'CODE STATES 44' 카테고리의 다른 글
주말공부:스코프, 클로저 복습 with Unit9 종합퀴즈 (0) | 2023.03.19 |
---|---|
Bees (프로토타입 체인 과제 해설) (0) | 2023.03.16 |
자주 쓰이는 터미널 명령어, Git 명령어 (0) | 2023.03.15 |
객체 지향 프로그래밍 1-3) 프로토타입과 클래스 (0) | 2023.03.15 |
객체 지향 프로그래밍 1-2) 절차 지향 vs 객체 지향 (0) | 2023.03.15 |