본문 바로가기
javascript

자바스크립트 프로토타입 개념이 어려운 사람들을 위해

by 윤-찬미 2021. 3. 1.

📋 목차

  • 서론
  • 함수 객체의 내부구조
  • 프로토타입(prototype)과 프로토(proto), 프로토체인이 뭐야?
  • 왜 사용하는거야?
  • 코드의 재사용, 상속에 대하여
  • 참고자료

✔️ 서론

자바스크립트를 막 공부하기 시작한 자린이(자바스크립트 어린이) 분들이나, 자바스크립트에 대해 깊이 공부 해보신적 없는 모든 분들 중에 혹시 프로토타입을 잘 모르고 계신다면 읽어보시면 좋을 것 같습니다.

잘못된 정보나 피드백, 이해하기 어려운 부분이 있으시면 댓글 부탁드립니다.

✔️ 함수 객체의 내부구조

Javacript 에서는 함수를 정의하고, 파싱단계에 들어가면, 내부적으로 수행되는 작업이 있습니다.

아래와 같은 함수를 정의할때 어떤일이 벌어지는지 한번 알아보겠습니다.

function Dog() {}

1.해당 함수에 Constructor 자격 부여

Constructor 자격이 부여되면 new를 통해 객체를 만들어 낼 수 있습니다.

 

2. 해당 함수의 Prototype Object생성 및 연결

함수를 정의하면 함수가 생성됨과 동시에 Prototype Object도 같이 생성됩니다.

 

🙋🏻‍♀️ 프로토타입(prototype)과 프로토(proto) , 프로토체인이 뭐야?

프로토타입(prototype) ?

그림에서 보시다 싶이 함수가 생성되면 프로토타입 오브젝트가 생기는데, 이 프로토타입 오브젝트가 앞으로 new 연산자를 사용해 생성된 객체의 원형이 되는 객체라고 생각하시면 됩니다.

 

프로토(proto) ?

Prototype Link 입니다.

아까 원형을 의미하는 프로토타입 객체를 참조하는 숨겨진 링크가 있습니다.

아래에서 좀 더 자세하게 알아보도록 하겠습니다.

prototype 속성은 함수만 가지고 있던 것과는 달리

proto 속성은 모든 객체가 빠짐없이 가지고 있는 속성입니다.

아래코드를 한번 살펴보겠습니다. Dog라는 함수를 생성하고, new를 통해 객체를 생성해주었습니다.

 

function Dog() {}
const myDog = new Dog(); 

new 로 myDog객체가 만들어 졌고 내부에서 _proto_에는 원형객체를 가르키는 링크가 들어있습니다!

그림을 바탕으로 설명하면 아래와 같습니다.

 

  1. function Dog() {} 로 함수를 만든다.
  2. 함수가 생성되면 Constructor자격이 부여되고,(Constuctor 자격이 부여되면 new 로 객체를 만들 수 있습니다.) prototype 객체가 생기는데 이 prototype객체에는 constructor와 proto 라는 속성이 들어가있다.
  3. new 를 통해 객체를 만들어 내면 내부적으로 proto 가 생기며 이 _proto_는 원형객체(그림으로 치면 Dog prototype Object) 를 참조하는 링크 입니다.

3번 설명에 따라 아래와 같은행위를 취할 수 있습니다.

function Dog() {}
Dog.prototype.hobby = '잠자기';
Dog.prototype.food = '사료';
const myDog  = new Dog();
console.log(myDog.hobby); // => 잠자기

new로 생성된 myDog는 내부에서 proto 를 통해 Dog Prototype Object 를 참조하고 있기 때문에

Dog prototype에 추가 된 속성들을 불러 사용할 수 있습니다.

 

console에 찍어 직접 확인해 보세요!

프로토체인?

프로토체인은 간단합니다. 결론부터 말씀드리면 속성을 찾을때까지 상위 프로토 타입을 탐색한다! 입니다.

그렇게 상위까지 올라갔는데도 못찾으면 undefined를 반환합니다.

function Dog() {}
Dog.prototype.hobby = '잠자기';
Dog.prototype.food = '사료';
const myDog  = new Dog();
console.log(myDog.hobby); // => 잠자기
console.log(myDog.name); // =>  undefined

 

🙋🏻‍♀️ 왜 사용하는거야?

이쯤되면 아니대체 왜저렇게까지 사용하는거야? 너무 어려워! 라는 의문이 들 수도 있습니다.

결론만 얘기 하면 "불필요한 메모리 낭비 방지" 입니다.

대표적인 예로 아래와 같은 상황을 들 수 있습니다.

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개의 변수가 메모리에 할당되겠죠?

 

바로 이런 문제를 프로토타입으로 해결할 수 있겠죠?

 

🙋🏻‍♀️ 코드의 재사용, 상속에 대하여

자바와 같은 언어를 먼저 접하신 분이라면 클래스 개념이 있어서 중복된 코드를 상속 받아 코드를 재활용 할 수 있습니다. 하지만, Javascript에서는 클래스가 없는 프로토타입 기반 언어 입니다. 따라서 프로토 타입을 이용하여 코드를 재사용 할 수 있습니다.

 

🖐🏻 잠깐!

ES6에 class가 생긴거 아닌가요?

아뇨, 정확히 말하면 javascript에는 클래스가 없습니다. 그저 oop에 익숙한 개발자들을 위한 문법 설탕 입니다.

 

javascript에는 프로토타입을 이용한 상속이 두가지 방법이 있습니다.

  1. classical 방식
  2. prototypal 방식 - Object.create()

Javascript에서는 prototypal 방식을 사용합니다. 이유는 더 간결하게 구현할 수 있기 때문입니다.

classical 방식을 사용하면 여러 고려해야할 상황도 많습니다.

 

이번 포스팅에서는 prototypal방식 을 이용해서 간단하게 상속을 구현해보겠습니다.

 

이 방법은 Object.create()를 사용하여 객체를 생성과 동시에 프로토타입객체를 지정합니다.

이 함수는 첫 번째 매개변수는 부모객체로 사용할 객체를 넘겨주고,

두 번째 매개변수는 선택적 매개변수로써 반환되는 자식객체의 속성에 추가되는 부분입니다.

이 함수를 사용함으로 써 객체 생성과 동시에 부모객체를 지정하여 코드의 재활용을 간단하게 구현할 수 있습니다.

 

const dog = {
    type : "animal",
    getType : function(){
        return this.type;
    },
    getName : function(){
        return this.name;
    }
};

const myDog = Object.create(dog);
myDog.name = "라이";

console.log(myDog.getType());  // animal
console.log(myDog.getName());  // 라이

부모 객체에 해당하는 dog을 객체 리터럴 방식으로 생성했습니다. 그리고 자식 객체 myDog은 Object.create() 함수를 이용하여 첫 번째 매개변수로 dog을 넘겨받아 myDog 객체를 생성하였습니다. 한 줄로 객체를 생성함과 동시에 부모객체의 속성도 모두 물려받았습니다.


지금까지 프로토타입에 대해 간단히 알아보았습니다.

생각보다 어려운 개념은 아니니 찬찬히 읽어보시면 분명 금방 이해하실 겁니다.

직접 콘솔로 내부를 출력해보고 확인해보는 것이 도움이 될 것이라 생각합니다.

다양한 피드백은 환영이니 언제든 댓글 달아주세요!

 

👣 참고자료

https://www.nextree.co.kr/p7323/

https://medium.com/@bluesh55/javascript-prototype-이해하기-f8e67c286b67