아까 쓴 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
__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는 새로운 주소값을 가지고 새로운 프로토타입 객체를 만들어 낸다!
어쨌든 이건 올드한 코드라고 볼 수 있다고 한다.
한눈에 봐도 너무 어렵..
그럼 최신 방법을 좀 살펴볼까??
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문법 없었으면 어쩔뻔했니..🌝
블로그 작성 진짜 끝 !