- prototype, __proto__, constructor의 관계와 프로토 타입 체인 정리
- Object.create() 정리
- ES6의 Class 키워드와 super 키워드 정리 및 psedoclassical 과의 비교를 통한 프로토타입 체인 정리
Instantiation patterns
class(blueprint)로부터 instance를 만드는 것 (비유를 하자면 붕어빵 찍는 기계에서 붕어빵을 찍어낸다고 생각!!)
4가지 패턴이 있다
1. functional
객체 안에 프로퍼티와 메소드를 객체의 키값 형태로 직접 만듬
2. functional shared
객체 안에 프로퍼티를 만드는 방법은 동일하지만 메소드는 함수 밖에 임의의 메소드만 담을 객체를 만들고 인스턴스를 만들 때마다 메소드를 담은 객체를 참조하게 하는 방법 -> functional 보다 좀 더 효율적!!
3. prototypal
shared와 거의 유사하지만 메소드를 담은 객체를 Object.create 를 통하여 __proto__를 통해 참조할 수 있도록 함
4.psedoclassical
앞에 방법들과는 달리 생성자 함수를 통하여 instance를 new 키워드를 통하여 만들고 함수의 프로토 타입에 메소드를 정의하여 instance가 자신의 부모 클래스의 함수 메소드를 이용할 수 있도록 함 (prototype을 기반으로한 class)
앞에 1~3번까지의 방법은 사실 OOP를 흉내내어 편법적(?)으로 구현한 것이고 사용하기도 번거롭다. (그럼에도 저런 방법들을 알고 있어야 자바스크립트가 class를 어떻게 구현하는지, 상속이 어떻게 이루어지는지, ES6에서 class키워드가 왜 나왔는지 알 수 있을 것 같다.) 그래서 뒤에 나올 설명들은 4번의 방법을 가지고 설명을 할 것이다.
Instantiation 에서 prototype, __proto__, constructor
function Human(name) {
this.name = name;
}
Human.prototype.sleep = function () {
console.log(`${this.name} 자는중...`)
}
let human1 = new Human("kim");
human1.name // "kim"
human1.sleep() // "kim 자는중..."
먼저 모든 객체는 함수로 생성된다. (array나 object, function 등 모두 동일) 그리고 함수가 만들어질 때 모든 함수는 prototype 객체를 갖게된다. 이 프토토타입 객체안에는 기본적으로는 constructor와 __proto__를 갖고 있다.
constructor는 생성한 함수를 가리키고 있다. 그래서 new 키워드를 통하여 새로운 객체를 만들어 낼 수 있다.
그리고 __proto__는 부모 함수의 프로토타입 객체를 가리키고 있다.(참조하고 있다?)
(참고로 모~든 객체는 전부 __proto__를 기본적으로 가지고 있음)
위의 예시에서 human1을 까보면
- 먼저 프로퍼티로 name을 가지고 있고 name은 "kim"
(this는 이때 인스턴스 객체를 가리키기때문에 this.name은 인자로 받은 "kim"이 된다)
- sleep 메소드는 human1 객체가 자체로는 가지고 있지 않다. 하지만 사용이 가능!! -> 프로토타입 체인
- human1이 함수가 아닌 객체이기 때문에 프로토타입은 없고 __proto__가 있음
- instance가 생성될 때 __proto__는 인스턴스를 만든 부모 함수의 프로토타입을 참조하고 있다 (즉, Human의 프로토타입을 참조)
- Human의 프토토타입 객체에 sleep이라는 메소드를 만들어 주었고 human1은 Human의 프로토타입을 참조하고 있기 때문에 인스턴스에는 sleep 메소드가 없지만 __proto__를 통하여 Human의 프로토타입에 접근이 가능하고 거기에 sleep이 있기 때문에 사용가능!! (이것이 프토토타입체인)
그러면 Human은 어떻게 되어 있을까?? Human을 까보면
- Human은 함수이기 때문에 프로토타입 객체를 가지고 있고, 또한 함수도 어떻게보면 함수(Funciton 으로 생성됨)로 생성되는 객체이다!! 그렇기 때문에 __proto__를 마찬가지로 가지고 있고, 이 __proto__는 부모 함수인 Function의 프로토타입 객체를 가리키고 있다. 그리고 이 Function 또한 마찬가지로 함수이고, Function의 프로토타입 객체이기 때문에 이 프로토타입 객체안에 컨스트럭터와 __proto__를 가지고 있다. 이때의 __proto__는 최상위인 Object의 프로토타입 객체를 가리키고 있음!!
-Human의 프로토타입 객체 안에는 컨스트럭터가 있고, Human 함수 자체가 들어있다.
- 프로토타입 객체이기 때문에 마찬가지로 __proto__는 최상위인 Object의 프로토타입 객체를 가리키고 있다.
__proto__는 결국 프로토타입 체인을 통해 최상위 Object의 프로토타입을 참조할 수 있기 때문에 Object의 프로토타입에 정의되어 있는 모든 메소드를 자식 함수 혹은 객체에서 모두 사용이 가능!!!
최상위 Object의 __proto__는 null이다.
이러한 prototype과 constructor, 그리고 __proto__을 통하여 프로토타입 체인이 이루어지고 생성자 함수(class)를 통하여 인스턴(instance)가 만들어지고 그때 부모 함수의 메소드나 프로퍼티를 참조하여 사용할 수 있는 것이다!!!! (instantiation)
'JS' 카테고리의 다른 글
(191222) Common JS & ES6 Modules (0) | 2019.12.22 |
---|---|
(191128) Instantiation & Inheritance (2) (0) | 2019.11.28 |
댓글