CoreJavaScript Chapter 6. [Prototype]

JUGNMIN LEE·2021년 6월 6일
0

CoreJavaScript

목록 보기
6/7
post-thumbnail

요번 챕터는 프로토타입 에 대해서 확인해보려 한다 !
자바스크립트는 프로토타입의 언어이기 때문에 그에 대한 개념을 알고가자!

CoreJavaScript

1. Prototype ??

프로토 타입이란 무엇일까 ?

자바스크립트는 프로토타입의 언어이다 그렇기에 클래스 기반의 언어에서는 상속을 사용하지만 프로토타입 기반 언어에서는 어떤 객체를 원형으로 삼고 이를 복제(참조)하여 상속과 비슷한 효과를 낼 수 있다

어떤 생성자 함수 constructor를 new 연산자와 함께 호출하면 새로운 인스턴스가 생성이된다 이때! 새롭게 생긴 인스턴스에는 __proto__라는 프로퍼티가 자동으로 부여가 된다.

이 프로퍼티는 아까 생성자 함수로 만든 constructor의 prototype이라는 프로퍼티를 참조하게 된다

constructor의 prototype 그리고 __proto__ 뭔가 어색하다

아니 그래서 언제 사용하고 어떻게 사용이 되는걸까?

아래의 코드로 확인해보자

function Person() {
  this.eyes = 2;
  this.nose = 1;
}
var kim  = new Person();
var park = new Person();
console.log(kim.eyes);  // => 2
console.log(kim.nose);  // => 1
console.log(park.eyes); // => 2
console.log(park.nose); // => 1

kim과 park은 eyes와 nose를 공통적으로 가지고 있는데, 메모리에는 eyes와 nose가 두 개씩 총 4개 할당이 되게 된다
그렇다면 만약에 객체를100개 만들면 200개의 변수가 메모리에 할당이 되어버리는거다 이런 문제를 해결하기 위해 프로토타입을 사용할 수 있다

function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
var kim  = new Person();
var park = new Person():
console.log(kim.eyes); // => 2
console.log(park.eyes); // => 2

어? Person이라는 빈 함수를 만들고 갑자기 prototype.eyes??

간단히 설명하자면 Person을 만들면 Person.prototype이라는 빈 Object가 어딘가에 존재하고, Person 함수로부터 생성된 객체(kim, park)들은 어딘가에 존재하는 Object에 들어있는 값을 모두 갖다쓸 수 있다.

즉!! eyes와 nose를 어딘가에 있는 빈 공간에 넣어놓고 kim과 park이
공유해서 사용하는 것이다.

그러면 프로토타입이 왜 이렇게 쓰이는지 조금 더 알아보자 !



2. How to use Prototype ?

위에서 설명한 내용을 다시 한번 이야기 해보자면
자바스크립트는 프로토타입의 언어이기에 다른 언어에 있는 클래스 상속등이 없다 하지만 ! ES6에서 클래스라는 문법이 추가 되었고 그렇다고 해서 다른 언어 처럼 상속을 사용하지는 않는다 대신에 어떤 객체의 원형을 참조(복사)하여 상속의 효과를 낼 수가 있으며 그 객체는 언제나 함수를 통하여 생성이 된다

또한 Prototype LinkPrototype Object라는 것이 존재하는데
이 두개를 통틀어 프로토타입이라고 부른다 만약 프로토타입을 이해했다는 것은 저 두개를 이해했다는 것과 같다

그러면 객체는 언제나 함수를 통해 생성이 된다 했으니

아래의 코드를 보면서 Prototype Object에 대해 설명해본다

function Test(){}
let helper = new Test(); // 함수로 객체를 생성함

const obj = {}; // 이렇게 빈 객체의 생성 또한
const obj = new Object(); // Object라는 자바스크립트가 제공하는 함수를 사용하여 생성한 것과 같다.

결국 함수다 !

Object와 마찬가지로 function, Array 모두 함수로 정의된다

만약 궁금하다면 개발자도구를 열어서 콘솔창에 Object를 쳐보면 native function이라 나올 것이다

아니 그러면 이게 왜 Prototype Object와 연관이 있을까 ?
또한 함수는 어떻게 new 키워드를 이용할 수 있을까?

그것은 Constructor(생성자) 자격이 부여 됬기 때문이다
생성자 자격이 부여되면 new를 통해 객체를 만들어 낼 수 있고
함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object도 같이 생성이 된다 함수의 역할을 하는 또 다른 녀석이 복제된다고 생각하면 이해가 될 수 있다

그리고 생성이 된 함수는 prototpe이라는 속성을 통해 같이 생성됬던
Prototype Object에 접근을 할 수 있고 Prototype Object의 경우
일반적인 객체와 같으며 기본적으로 constructor(생성자) __proto__를 가지고 있다

위의 사진을 보면 Good함수가 만들어져서 Prototype Object도 같이 생성이 됬고 Good함수는 prototype이란 속성을 통해 Good.prototype으로 같이 생성된 Prototype Object로 접근이 가능한 것이다.

여기 위 사진에서 Constructor는 Prototype Object와 같이 생성된 Good함수를 가르키고 있으며 __proto__Prototype Link가 된다

그러면 아래의 코드와 사진을 함께 보자

function Fruit(){}

Fruit.prototype.apple = 2;
Fruit.prototype.banana = 3;
let test1 = new Fruit();
let test2 = new Fruit();

console.log(test1.banana); // 결과값 : 3

코드와 사진을 보니 Prototype Object는 일반 객체라고 하였으니깐 속성을 마음대로 추가 삭제 수정 할 수가 있고 test1, test2의 경우 Fruit을 통해 생성되었으나 Fruit.prototype을 참조 할 수 있게 되었다

조금은? 이해가 되려고 한다 🤨

그렇다면 ! 어떻게 Fruit으로 만든 test1은 Fruit안에 banana라는 속성이 없는데 사용이 되었을까?

이때 사용되는 것이 아까 Prototype Link으로 소개했던 __proto__이다

prototype의 속성의 경우 함수만 가지고 있던 것과 달리
__proto__ 속성은 모든 객체가 전부 가지고 있는 속성이다

그래서 __proto__의 경우 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가르키게 된다

test1이라는 객체는 Fruit이라는 함수로부터 시작되었지만 Fruit 함수의 Prototype은 Object를 가르키고 있다 (아래의 사진 참고)

__proto__를 확인해보니 test1이라는 객체가 banana라는 객체를 직접 가지고 있지 않았는데도 불구하고 banana라는 속성을 찾기 위해서 상위 프로토타입을 탐색을 하게 된다 만약 최상위인 Prototype Object까지 도착했지만 값이 없으면 undefined를 반환하게 되며 이렇게 상위 프로토타입과 연결되어 있는 것을 프로토타입 체인 이라고 한다

그래서 이러한 프로토타입 체인 구조로 인해 가장 최상위는 자바스크립트가 가지고 있는 Object라는 함수의 프로토 타입인 Object Prototype Object에 있는 속성을 전부 사용할 수 있게 된다



후.. 정리를 하자면 ?
즉 함수를 생성하면 생성자 권한을 가질 수 있고 일반 객체인 프로토타입도 같이 생성이되며 일반 객체인 프로토타입은 추가 수정 삭제가 가능하며 Fruit이 new로 새로운 객체를 생성하면 그 해당 객체는 Prototype이라는 Fruit의 속성을 이용해 Prototype Object로 참조가 가능하게 된다
그 참조의 이유는 __proto__라는 모든 객체가 빠짐없이 가지고 있는 속성을 이용해 참조가 되며 이렇게 __proto__이란 속성을 이용해 상위 프로토타입과 연결되어 있는 형태를 프로토타입 체인! 이라고 한다 : )

ps. 프로토타입을 정리하면서 자바스크립트가 어떻게 사용이되고 상속을 어떻게 해결하고 있는지에 대한 이해가 도움이 됬다


출처
모든 내용은 코어자바스크립트 공부를 하며 책 내용을 발췌해 이해한 내용들만 추려 적은 내용입니다 해당 코드들은 책 내용의 코드의 값들을 변경하거나 이해를 위해 그대로 가지고 왔습니다.
https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

profile
Frontend Developer

0개의 댓글