이전 글에 중에 클로저를 설명하는 글에서,
내가 생각할 때 자바스크립트에서 개념적으로 가장 중요한 것이 두개있다고 했었다.
사실 세개다.....ㅠ
왜 두개라고 뭉겠었냐면 그 당시에 이 개념을 100% 이해하고 있지 못했다.
사실 지금도 100% 이해했다고 자신있게 말 못할것같다.
그래도 계속 이해하려 노력하고, 정리하면서 어느정도 이해가 되어 글을 작성해보려한다.
이 글에서 알아볼 것
- 프로토타입 (Prototype)
1. 프로토타입 (Prototype)
- 프로토타입이란?
- 자바스크립트는 프로토타입 기반 언어로, 프로토타입 상속을 사용한다.
- (예전에, 강의 듣다가 이 말 듣고 그냥 자러갔던 기억이있다..)
- 무슨 말인지는 밑에서 서술하겠다.
- 또한, 프로토타입은 객체로, 모든 객체는 프로토타입을 가진다. (__proto__)
- 또한, 프로토타입 객체는 Fallback 객체다.
- 자바스크립트는 프로토타입 기반 언어로, 프로토타입 상속을 사용한다.
- 3번부터 위로 올라가면서 알아보자
- 프로토타입 객체는 Fallback 객체다.
- 무슨말일까?..만약 person = {name: “messi”}라는 객체가 존재한다고 가정하자, 이때 person.age 를 엑세스할려해봤자, 되질 않는다.
- 하지만, 이때 자바스크립트 내부에서는 복잡한 작업이 일어난다.
- 자바스크립트가 해당 객체에서 찾지 못하면, 자동으로 프로토타입 객체를 살펴보고, 찾아본다. 거기도 없으면 그 프로토타입의 프로토타입…쭉 찾아본다
- 이게 어떻게 가능하냐면, 2번에서 말한대로 모든 객체는 프로토타입을 가진다. (__proto__)
- 객체를 console.dir로 찍어보자..__proto__라는 프로퍼티가 존재할것이다.
- 그래도 못찾으면 그때서야 못찾았다고 반환한다
- 이것의 예시는 person.toString()을 찍어보면..오류가 아닌 [Object Object]를 출력한다..여기서 중요한건 오류가 아니라는것이다,,
- 자바스크립트가 해당 객체에서 찾지 못하면, 자동으로 프로토타입 객체를 살펴보고, 찾아본다. 거기도 없으면 그 프로토타입의 프로토타입…쭉 찾아본다
- 이처럼 프로토타입은 fallback 객체이고, 모든 객체에는 프로토타입이 존재한다.
- 근데 person.toString()을 찍었는데 왜 오류가 안뜨는지 궁금할 것이다.
- 1번에서 자바스크립트는 프로토타입 기반 언어로, 프로토타입 상속을 사용한다. 라고 하였다.
- 이를 설명하는 것이 프로토타입 체인이다.
- 자바스크립트는 toString() 메서드를 일단 호출하고, 해당 객체(person) 자체의 일부인지 확인한다.
- 없다고 판단되면, 해당 객체의 프로토타입을 확인한다
- 또 없다고 판단되면, 2번 프로토타입의 프로토타입을 확인한다
- 이렇게 쭉…확인하다가, 마지막 프로토타입을 확인하는데, 이 마지막 프로토타입은 Object 의 프로토타입이다.
- 이는 console.dir(Object)를 찍어보면 자세히 살펴볼수있다
- 여기서 toString()을 찾아서 오류가 발생하지 않은것이다.
- 즉, 프로토타입 객체는 다른 객체(A객체)에서 정의되지 않은 프로퍼티나 메서드로 작업할 때 다른 객체(B객체)가 접근할 수 있는 "대체 객체" 같은 역할을 한다.
내가 글로 이 개념을 표현할 수 있는 것은 다 했다..
내가 다시 읽어봐도 난해하다.
코드로 다시 프로토타입을 이해해보자
class AgedPerson {
printAge() {
console.log(this.age);
}
}
class Person extends AgedPerson {
name = "Messi";
constructor() {
super();
this.age = 36;
}
dummyFn() {
console.log("name: " + this.name + "/ age: " + this.age);
}
}
// ==========================================================
function Person2() {
this.name = "Pedri";
this.age = 20;
this.dummyFn2 = function () {
console.log("name: " + this.name + "/ age: " + this.age);
};
}
Person2.prototype = {
printAge2() {
console.log(this.age);
},
};
console.dir(Person);
const p = new Person();
p.dummyFn();
p.printAge();
console.log(p.__proto__);
console.log("=========");
console.dir(Person2);
const p2 = new Person2();
p2.dummyFn2();
p2.printAge2();
console.log(p2.__proto__);
- ===== 위 아래 코드는 똑같은 작업을 수행한다.
- 여기서 알 수 있는것은 ==== 위의 코드에서는 AgedPerson 클래스가 Person 클래스의 프로토타입이고, 아래 코드에서는 printAge2() 메서드가 Person 클래스의 프로토타입이라는것이다. (위는 자동, 아래는 수동으로 작업한것)
*참고
콘솔로 객체를 찍었을 때 어떤 객체는 __proto__뿐만 아니라 prototype 도 출력된다.. 둘의 차이는 뭘까?
- __proto__ vs prototype
- __proto__ → 모든 객체에 존재한다. / 해당 객체의 프로토타입 객체를 뜻한다
- prototype → 오직 함수 객체에만 존재한다 / 객체를 할당할 때 사용된다(프로토타입으로 할당됨) = 함수 객체를 기반으로 생성된 객체에 프로토타입으로 할당될 프로토타입 객체를 뜻한다
정말 난해한 개념이지만,
자바스크립트를 좀 더 깊게 이해하게 해주는 개념이므로 꼭 이해하고 넘어가야하는 파트같다.
'OLD > Javascript' 카테고리의 다른 글
[Javascript] Prototype에 대한 이해 (0) | 2024.03.29 |
---|---|
[Javascript] this 키워드 알아보기 (0) | 2024.03.24 |
[Javascript] 자바스크립트 비동기(Async)_02 (콜백 지옥(Callback Hell), 프로미스(Promise), async/ await... ) (0) | 2023.02.28 |
[Javascript] 자바스크립트로 브라우저 저장소 이용하기 (LocalStorage, Cookies, indexedDB) (0) | 2023.02.27 |
[Javascript] 자바스크립트 모듈 (0) | 2023.02.26 |