[TIL] Immersive 05_2021.04.09 (Prototype Chain)

나라리야·2021년 4월 9일
0

TIL_Immersive course

목록 보기
6/9
post-thumbnail

아까 쓴 OOP 내용으로 오늘 블로그가 끝났더라면 참 좋았을테지만..👀
하나 더 정리해야하는데 이게 정말 끝판왕인거같아.. 구글링 좀 해보니깐 전공 대학생들도 한학기를 배우는 개념이라던데 오늘 배우고 개념을 익혀서 스프린트까지 끝내라니 이게 말이됩니까?🙈
하면서도 열심히 하고있다(ㅋㅋㅋ)
패턴을 배우라고 했으니 일단 코드의 패턴을 익히는게 우선일 것 같다 📖

서론이 너무 길었는데 어떤 내용을 정리해야하는지 미션을 보자!
__proto__, constructor, prototype 이 각각 어떤 관계를 가지고 있는지 조사해봅니다.
ES6 class 키워드 및 super 키워드 이용 방법을 알아봅니다.

왜자꾸 조사해보라고 하세여.. 🥲
코드보는 것도 버벅이고 있는데 말이져..😣
그래두 열시미해보자구!스타뚜!💪🏻

여기서 잠깐!

new 키워드를 이용해서 인스턴스 생성시 사용하는 this키워드에 대한 이해를 짚고 넘어가자

function Car (brand,name,color) {  //Car : class
  this.brand = brand;              //this 객체
  this.name = name;
  this.color = color;
}                                  // function {} : constructor(생성자) 함수

Car.Prototype.drive = function() { // Prototype 객체 (속성이나 메서드 정의 가능)
  console.log (this.name + "운전 중");
}

let Avante = new Car ('hyundai','avante','black');  // Avante : instance
avante.color; // black 출력
avante.drvie(); // `avante 운전 중` 출력

prototype : 원형객체(original form)
Constructor : 인스턴스가 초기화 될 떄 실행되는 생성자 함수
this : 함수가 실행 될 때 해당 scope 마다 생성되는 고유한 실행

__proto__, constructor, prototype 각각의 관계는?

function Human (name) {
  this.name = name;
}
Human.prototype.sleep = function () {};
let steve = new Human ('steve');

steve.__proto__  === Human.prototype   //true  -> 'steve'의 부모 prototype 프로퍼티에 대한 정보 참조한 값 : Human.prototype

steve.toString();   // '[Object Object]'  -> prototype chain 최 상단 : Object

prototype Property

__proto___
-모든 객체가 가지고 있는 속성
-부모의 prototype property에 대한 정보 참조
prototype
-함수 객체만이 가지는 prototype
-자신의 prototype 객체
-할당이 가능하다

이게 뭔 소리죠? 🤦🏻‍♀️
저기 여기 미아있어여! 프로토타입 체인 미아!! 데리고 가주세요..🙏🏻
Object가 제일 대빵, 최종보스!
..그러니까 __proto___를 타고 올라가면서 각 상위 객체들의 prototype을 모두 탐색할 수 있고.. 최종적으로 null을 만나서 탐색이 종료될 때까지 속성을 찾지 못하면 undefined를 반환한다?! 하핫

상속을 구현해볼까? (NOPE)

var Human = function (name) {
  this.name = name;  // class? 
}
Human.prototype.sleep = function () {}; // 생성자? 메소드?
var steve = new Human('steve'); // 인스턴스

var Student = function (name) {}
Student.prototype.learn = function () {}; //생성자? 메소드?
var john = new Student('john'); // 인스턴스
john.learn();
john.sleep();

steve instanceof Human === true;
john instanceof Student === true;
john instanceof Human === true;  // human의 상속값을 가진다?

살려주세요..ㅋㅋㅋ
그림으로 볼까요??? (NOPE)

그러니까 steve.sleep() 메소드 기능을 해야하는데.. Human.prototype.sleep가 이 메소드의 __proto__ 속성(?)인거고...Human.prototype.sleep이 Human class의 생성자였던것..? 맞게 가고있나요??.. 그리고 Human의 프로토타입이 Human.prototype.sleep 인거고.. 여기서 new 키워드로 생성된 steve라는 인스턴스에 Human이 가지고있는 메소드가 상속이된건가...? 너무 어렵당..🙉
주님.. 왜 저에게 이런 시련을?

pseudoclassical 상속 패턴

말그대로 해석하면 가짜로 class 개념을 흉내내는 방식? 야매?(ㅋㅋ)

var Human = function (name) {
  this.name = name;
}
Human.prototype.sleep = function () {};
var steve = new Human('steve');

var Student = function (name) {
     Human.call(this,name);  // Human.apply(this,arguments)  가능 
}
Student.prototype = Object.create(Human.prototype); 
Student.prototype.constructor = Student;   
Student.prototype.learn = function () {};
Student.prototype.sleep = function () {
Student.prototype.sleep.bind(this);  // Human.prototype.sleep에 추가 하고 싶다면 이 줄 가능
//왜 apply 아닌 bind이지요?
console.log ();
}

var john = new Student('john');
john.learn();
john.sleep();

Object.create 안쓰면 안되나???!!
안된다고한다..
아래의 예제를 보자

Student.prototype = Human.prototype;  // wrong

Student.prototype = Object.create(Human.prototype) // correct 

위에 있는 코드는 부모 생성자 함수의 prototype을 그대로 갖다 붙였는데 이때 부모 생성자 함수의 주소값까지 그대로 가져와서 두함수가 아예 동일시 되버린다. 즉, 두 함수가 연동되어서 student에 속성을 추가하면 human 함수에도 속성이 추가되어 결과적으로 동일한 함수가 되버리는 것!

근데 우리가 만들어야할 건 부모 생성자 함수에 속성이 추가되면 자식 생성자 함수들도 언제든 공유받을 수 있지만 각 자식 생성자 함수들에 속성이 추가가 되어도 부모 생성자 함수는 영향받지 않는 별개의 함수를 만들고 싶은 것이다!
얕은 복사를 실행하는 Object.create가 이 역할을 해주는 것, Object.create는 새로운 주소값을 가지고 새로운 프로토타입 객체를 만들어 낸다!

어쨌든 이건 올드한 코드라고 볼 수 있다고 한다.
한눈에 봐도 너무 어렵..
그럼 최신 방법을 좀 살펴볼까??

ES6 class 키워드 및 super 키워드 이용 방법을 알아봅니다.

pseudoclassical에서 복잡하게 구현했던 내용을 새롭게 적용된 키워드를 통해 간단하고 명료하게 구현할 수 있게 되었다! (패턴을 외우자) 👓


class Human {
constructor(name) {
  this.name = name;
}
  sleep () {
  }
}
var steve = new Human('steve');
class Student extends Human {
  constructor(name) {      // 자식 constructor부분 생략가능 (부모-자식 constructor args 같음)
    super(name);
  }
  learn () {
  }
}
var john = new Student('john');
john.learn();
john.sleep();

블로그는 작성했지만.. 코드패턴을 외우는게 제일 빠른길이란걸 느껴버렸다🐸
ES6문법 없었으면 어쩔뻔했니..🌝
블로그 작성 진짜 끝 !

profile
Code의 美를 추구하는 개발자 🪞

0개의 댓글