📋 목차
- 서론
- 함수 객체의 내부구조
- 프로토타입(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_에는 원형객체를 가르키는 링크가 들어있습니다!
그림을 바탕으로 설명하면 아래와 같습니다.
- function Dog() {} 로 함수를 만든다.
- 함수가 생성되면 Constructor자격이 부여되고,(Constuctor 자격이 부여되면 new 로 객체를 만들 수 있습니다.) prototype 객체가 생기는데 이 prototype객체에는 constructor와 proto 라는 속성이 들어가있다.
- 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에는 프로토타입을 이용한 상속이 두가지 방법이 있습니다.
- classical 방식
- 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
'javascript' 카테고리의 다른 글
롤업과 웹팩의 차이점 (rollup vs webpack) (2) | 2021.04.22 |
---|---|
자바스크립트 클로저가 아직도 난해한 개념으로 다가오는 사람들 모여라! (6) | 2021.03.05 |
자바스크립트 비동기 처리 - callback 과 promise (0) | 2020.11.10 |
this - 화살표함수와 일반함수 (0) | 2020.11.09 |
실행컨텍스트 - 자바스크립트야 왜 그렇게 동작하니? (0) | 2020.09.25 |