JavaScript Prototype

블레어(blair)·2020년 6월 11일
2

JavaScript

목록 보기
1/4
post-thumbnail

개요

  • 프로토타입이란 한마디로 JS에 존재하는 프로토타입객체라는것과 프로토타입링크라는것 두가지를 의미합니다.
  • js에서는 클래스는 없지만 비슷하게 흉내내기 위해서 function과 생성자 함수를 사용할 수 있습니다.
  • 객체의 공장이 될 함수가 생성이 될떄는 동시에 프로토타입 객체라는 게 생성이 됩니다.
    - 생성된 함수에는 프로토타입이라는 속성이, 프로토타입 객체에는 constructor라는 속성이 서로를 가르키면서 이 둘은 연결이 되어있습니다.
  • 생성자 함수로 객체가 만들어지면 그 객체의 프로토타입 링크라는 속성은 자신을 만든 함수의 프로토타입 객체를 바라보게 되는데요.
    - 이러한 이유로 생성자 함수로 만들어진 객체들이 프로토타입객체의 속성을 공유할 수 있습니다.
  • 프로토타입 링크는 사실 모든 객체가 갖고있는 속성인데요 프로토타입 객체또한 객체이기 때문에 그 상위 프로토타입객체를 바라보게되고 이 로직이 반복적으로 연결되서 결국 최상위인 오브젝트 프로토타입 객체까지 연결되는 형태를 프로토타입 체이닝이라고 합니다.

위 내용을 아래에 자세히 정리해 보려합니다.


프로토타입 속성?

const Foo = {firsr : 1}
Foo.prototype.a='hello world'; // Cannot set property 'a' of undefined
const boo = new Foo(); // error => foo is not a constructor
// 위 코드는 왜 에러가 날까? new생성자 함수 자격은 함수에게만 생긴다.

const Foo = function(){}
Foo.prototype.a='hello world';
console.log(Foo.prototype.a) // hello world

JS, C, Java는 모두 객체지향 언어이지만 JS는 Class를 갖고있지 않다(물론 ES6에서 생기기는 했지만 흉내는 내는것이지 Class기반의 언어로 바뀌었다는것은 아니다.)

즉 JS는 prototype기반의 OOP언어이다.
JS는 함수와 new를 통해서 클래스 비스무리하게 흉내를 낼 수가 있다.
객체를 반환하는 함수를 만들고 그 함수를 다른 변수에 new를 이용해서 인스턴스화 시킬 수 있다.

자바스크립트는 함수가 생성될때 일어나는 일이있다.

  1. 가령 Person함수가 생성된다.
  2. Person함수에는 Constructor(생성자)자격 부여된다.
    (생성자 자격이 부여되면 new를 이용해서 객체를 생성할 수 있다.)
    (이것이 함수만 new를 사용할 수 있는 이유이다.)
    (생성자 함수를 통해 생성된 객체 = 인스턴스)
  3. Person 함수의 Person Prototype Object 도 같이 생성된다.
  4. Person 함수에는 기본속성으로 prototype 이라는 프로퍼티가 생기고 이 프로퍼티는 Person Prototype Object 를 바라본다.
    (여기서 이 prototype란 속성은 함수에만! 생기는 프로퍼티이다. 즉 그냥 객체에는 생기지 않는다.
    때문에 위의 코드에서 Foo라는 객체를 만들고 prototype를 추가했을때 에러가 발생되었던 것 이다.)
  5. Person Prototype Object에는 기본속성으로 constructor프로퍼티와(이 프로퍼티는 생성된 Person함수를 바라본다.
  6. Prototype Object에는 기본속성으로 __proto__ 프로퍼티도 생긴다. (이것이 바로 Prototype Link 이다.)

function Person () {
	this.eyes = 2;
	this.nose = 1;
}

const kim = new Person();
console.log(kim); // {eyes: 2, nose: 1}

Person.prototype.first = 1;
console.log(kim.first) // 1

Person 함수는 위에서 봤듯이 생성자자격이 부여되므로 new를 통해 객체를 찍어낼 수 있다.

prototype이라는 속성은 함수에만 생기지만 __proto__란 속성은 모든~ 객체에 빠짐없이 생기는 속성이다.
__proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다.
(⇒ 프로토타입 체인 : 이렇게 __proto__속성을 통해 상위 프로토타입과 연결되어있는 형태를 프로토타입 체인(Chain)이라고 한다.)
따라서 아래 그림처럼 kim객체는 Person함수로부터 생성되었으니 Person 함수의 Person Prototype Object를 가리키고 있는 것이다.


kim.first을 찍었을때 kim은 first라는 속성을 갖고있지 않았으면 찾을때까지 상위 프로퍼티를 계속 탐색한다.
탐색의 끝은 가장 최상위인 Object 함수의 Prototype Object까지 탐색해보고 그래도 없다면undifined를 리턴하게 된다.

위 그림과 같은 프로토타입 체인 구조 때문에 모든 객체는 Object의 자식이라고 불리고, Object Prototype Object에 있는 모든 속성을 사용할 수 있다.
한 가지 예를 들면 toString함수가 있다.

javascript에서 new키워드를 사용하여 생성된 모든 instance(=객체)는 prototype에 탑재된 기능을 사용할 수 있게 생성이 된다. ( prototype chain의 기본적인 효과 )

관련해서 생각해볼 것들

  • 프로토타입은? 프로토타입객체, 프로토타입 링크

  • 프로토타입객체는? 함수와 동시에 생성되는 객체(서로 바라봄)

  • 프로토타입링크는? 어떻게 동작하나요? 생성자로 만들어진 객체의 기본속성(조상함수의 프로토타입 객체를 바라봄) - 프로토타입객체속성 공유가능한 이유

  • 프로토타입 체이닝이 동작하는방식은? 프로토타입링크→상위 프로토타입객체바라봄 ⇒ 최상위 오브젝트 프로토타입객체까지 연결된 형태임

  • prototype 이 가진 장점은 무엇인가? 프로토타입의 속성을 객체들이 공유→메모리 낭비 줄일 수 있다.

  • prototype 기반 상속은 어떻게 하는지 설명해주세요.

  • prototype이 없을떄의 비효율적인 점? 객체가 생성될때마다 속성이 생겨 메모리 효율낮음

  • prototype 을 통해 객체를 만드는 방법에 대해서 설명하기.

  • JS의 상속?

참고자료

profile
프론트엔드 개발자 블레어의 개인 블로그 입니다. 개발공부를 하며 나누고 성장하고 싶습니다 :)

1개의 댓글

comment-user-thumbnail
2020년 6월 12일

깔끔한 정리 잘 읽었습니다 ! :)

답글 달기