JS prototype

이 대체뭔가요?

JavaScript로 코딩을 하다보면 한번쯤 들어봤을 prototype. 대체 이게 뭘까요? 무엇이길래 그렇게 중요하다고 할까요?

본 내용은 제가 prototype에 대해서 공부하며 깨달은 점과, 알아본 점이기 때문에 틀릴 가능성이 무척이나 높다는 것을 미리 밝히겠습니다. 😢

prototype?

엥? prototype? __proto__???

위의 printHi함수는 콘솔창에 ‘hi’ 를 출력해주는 무척이나 간단한 함수입니다. 이 함수의 내부를 펼쳐보면 위와같은 모습을 볼 수 있습니다. 만들지도 않은 prototype과 __proto__가 존재하죠. 대체 이게 뭐죠?

자바스크립트에는 Prototype LinkPrototype Object라는 것이 존재합니다. 그리고 이 둘을 통틀어 Prototype이라고 부릅니다. 위에서의 prototype은 prototype Object, __proto__는 prototype Link라고 볼 수 있습니다. 위의 내용을 자세히 설명하기 전에 Prototype Object에 대해서 알아봅시다.

Prototype Object

이게 무슨 소리인고 싶다구요? 객체는 언제나 함수로 생성됩니다. 증명 해볼까요?

fooObject 객체는 Foo라는 함수로 생성된 객체입니다. 이렇듯 언제나 객체는 함수에서 시작됩니다.

  • 그냥 const obj = {} 로 만들었다만?? 이게 함수랑 연관? 😛

제가 멋모르고 시작할 때 부터 쓰던 방법 이군요! 하지만 이것도 위와 별반 다를게 없습니다. 아래의 코드를 보시죠.

1번째라인의 코드를 보면 함수와 전혀 상관이 없어 보이지만 실상은 2번째라인의 코드와 같습니다. 
 위 코드에서 Object()는 JS에서 기본적으로 제공해주는 함수입니다.

Object너마저…

Object와 마찬가지로 Function, Array도 모두 함수로 정의되어 있습니다.

그렇다면 이것이 Prototype Object랑 무슨 상관이있느냐구요? Prototype Object 에대해 말한다고 해놓고 무슨 딴소리냐구요? 
 함수가 정의될 때는 2가지 일이 동시에 이루어집니다.

1.해당 함수에서 Constructor(생성자)함수를 사용할 수 있습니다.

위에서 prototype내에 있는 ‘{constructor: ƒ}’ 를 보셨었나요? 못보셨다면 위에서 다시 보고오세요.
 저희는 이 Constructor 함수로 인하여 new를 통해 객체를 만들어 낼 수 있게 됩니다. 이것이 함수만 new 키워드를 사용할 수 있는 이유입니다.

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

함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object도 같이 생성이 됩니다.

아…왜이모양이지..

위의 내용은 prototype내에 constructor가 있고 constructor내에 prototype이 있고.. 그게 영원히 이어지는 그런 것이 아닙니다. 단지 foo.prototype은 ({constructor ƒ}) 를 가리키고 foo.prototype.constructor는 다시 foo() {}를 가리키기 때문에 계속 영구적으로 나올 뿐입니다.

그리고 생성된 함수는 prototype이라는 속성을 통해 Prototype Object에 접근할 수 있습니다. Prototype Object는 일반적인 객체와 같으며 기본적인 속성으로 위에서 보셨듯 constructor 와 __proto__를 가지고 있습니다.

__proto__….!!

-__proto__?? Prototype Link어쩌구 하지 않았나? 🤔

네 맞습니다. 자. 우리 새로운 함수를 하나 만들고, 그 함수로 객체를 만들어볼까요?

이렇게 짜면 pomeranian.legs 가 4가 나옵니다. 그런데.

?

pomeranian객체 내에는 __proto__밖에 없는데? 어떻게 4의 값을 가져온 것 일까요? 바로 이 __proto__가 그것을 가능하게 해줍니다.

!

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

위의 스크린샷을 보면 알겠지만, __proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킵니다. pomeranian객체는 dog함수로부터 생성되었으니 dog함수의 Prototype Object를 가리키고 있겠군요.

그러하다!

pomeranian객체가 legs를 직접 가지고 있지 않기 때문에 legs를 찾을떄 까지 계속해서 프로토타입을 탐색합니다. 최상위의 객체에 도달했는데도 불구하고 값이 존재하지 않을 경우, undefined를 반환해줍니다. 그리고 이걸 바로 Prototype Chain이라고 합니다.

  • 설명이 빈약해서 무슨 말인지는 모르겠다. 뭐 그건 그렇고 프로토타입 뭐시기를 대체 왜 쓰나? 😠

…..

프로토타입이 존재하는 이유는 메모리의 효율성을 증가시키기 위해서 입니다! 모든 객체지향적 언어들의 상속을 자바스크립트가 이것을 사용함으로써 따라했다고 합니다.(뇌피셜)

객체와 객체가 서로 같은 역할을 하는 메서드들을 가지고 있습니다., 그리고 그런 객체가 100개가 있다고 칩시다. 그러면 100개의 객체내에 있는 같은 역할을 하는 메서드 100개가 ‘따로’ 존재해서 메모리를 잡아먹습니다. 이와 같은불합리성을 해결하기 위해서 프로토타입이 존재합니다.

예를 들어봅시다.

두개의 코드는 모두 bark함수를 호출 했을 때, 아무런 문제 없이 실행되지만 한 가지 다른점이 있습니다.

위의 proto에 bark라는 함수가 생겼습니다. 이렇게 만들게 되면 우리가 이 객체를 수십 수백개를 만들더라도, 저 bark라는 메서드는 __proto__안에 하나만 저장되고, 각각 따로 만든 객체에는 따로 저장하지 않고서도 사용할 수 있습니다. 이렇게 됨으로써, 메모리 사용을 줄일 수 있습니다.

class의 사용에 관해서는 이곳 을참조해주세요.

마무리하며

처음 써보는 기술관련 글이라 잘 썼는지, 남이 읽었을 때 이해하는데 조금이나마 도움이 될지 잘 모르겠네요. 아직 개발자라고 불리기도 민망한 사람이니 적극적인 피드백은 언제나 환영합니다. 끝까지 읽어주셔서 감사합니다 😃

참조한 곳

1.
2.