(학습을 진행하면서 내가 이해하고 공부한 부분을 기록합니다!)
자바스크립트란 프로토타입 기반의 언어입니다. 프로토타입은 자바스크립트 자체라고도 할 수 있다고 합니다.
위 질문은 C++, java같은 객체지향 언어에서 클래스란 무엇인가와 비슷한 질문이라고 합니다. 객체 지향언어에서는 Class 안에 기술된 내용을 기반으로 인스턴스를 생성하여 객체를 사용합니다.
하지만 객체지향언어인 자바스크립트는 클래스라는 개념이 없습니다.(물론 ES6에서 Class 문법이 추가 되었지만 문법이 추가 된 것이지 클래스 기반으로 변경되었다는 의미는 아닙니다.) 그럼 어떻게 상속기능을 사용할 수 있을까요? 대신 자바스크립트에서는 Prototype이 존재합니다 ^^...
자바스크립트는 객체의 원형인 prototype을 이용하여
복사
와,상속으로 인한 객체 특성 확장
을 통하여 새로운 객체를 생성합니다.
아래와 같은 코드가 있습니다.
function Cat(){
this.leg = 4;
this.tail = 1;
}
var gu = new Cat();
var rem = new Cat();
var eee = new Cat();
gu, rem, eee는 각각 leg, tail을 공통적으로 가져고 있습니다. 총 6개가 메모리에 할당되겠죠. 그러나 생성한 객체가 3개에 그치지 않고 그 보다 훨씬 많이 만들어야 한다면 그 보다 더 많은 데이터가 메모리에 할당이 되어야합니다.
하지만, 위의 코드를 prototype이라는 키워드를 사용하여 방지 할 수 있습니다.
function Cat(){}
Cat.prototype.leg = 4;
Cat.prototype.tail = 1;
var gu = new Cat();
var rem = new Cat();
var eee = new Cat();
이 코드는 leg, tail을 다른 공간에 넣어두고 gu, rem, eee와 공유하여 사용하고 있습니다.
Cat.prototype
이라는 빈 Object가 어딘가 존재하고 Cat함수로 만들어진 객체들(gu,rem,eee)은 그 빈 Object에 들어있는 값
을 사용할 수 있습니다.
자바스크립트는 Prototype Object와 Prototype Link라는 것이 존재합니다. 이 둘을 Prototype이라고 일컷습니다.
우선, 객체는 함수를 통해 생성 됩니다.
function Cat() {}
var catObjec = new Cat();
일반적으로 객체를 생성하는 경우 또한 아래와 같습니다.
var obj = new Object(); // var obj = {}
//Object는 자바스크립트에서 기본적으로 제공하는 함수입니다.
//Fuction, Array 모두 마찬가지 입니다.
이렇게 객체는 함수로 생성된다는 것을 확인했습니다.
함수를 정의 될 때는 해당함수에,
1. Constructor(생성자) 자격이 부여됩니다.
생성자 자격이 부여되면 new 키워드를 통해 객체를 만들어 낼 수 있게 됩니다. 그래서 함수만 new 키워드를 사용할 수 있습니다.
2. 해당함수의 Prototype Object 생성 및 연결합니다.
생성된 함수는 prototype이라는 속성을 통해 Prototype Object에 접근할 수 있습니다. 속성으로는 constructor
,__proto__
를 가지고 있습니다.
위에서 생성한 Cat 함수로 확인해 보겠습니다.
Cat.prototype
< leg: 4, tail: 1, constructor: ƒ}
leg: 4
tail: 1
constructor: ƒ Cat()
__proto__: Object
Prototype Object
는 객체이기 때문에 속성을 추가하고 삭제할 수 있습니다.
자신을 통해 만들어질 객체의 원형이라는 것을 이해할 수 있습니다.
Cat함수로 만든 객체 gu를 이용하여 gu.leg를 실행하면 Prototype Object에 존재하는 leg의 속성을 참조하여 4라는 값을 냅니다. 이는 gu가 가지고 있는 속성 __proto__
덕분입니다.
> gu
< Cat {}
__proto__: Object
prototype 속성은 함수만 가질 수 있지만 __proto__
속성은 객체도 가집니다.
그럼 __proto__
는 무슨 값을 담고 있을까요?
객체가 가지고 있는 __proto__
는 그 객체가 생성될 때의 조상인 함수의 Prototype Object를 가리킵니다.
> gu.__proto__
< {leg: 4, tail: 1, constructor: ƒ}
leg: 4
tail: 1
constructor: ƒ Cat()
__proto__: Object
객체 gu의 속성__proto__
는 함수 Cat의 Prototype Object를 가르키네요!
이를 통해 Prototype Object는 자신을 통해 만들어질 객체의 원형이고, Prototype Link는 자신을 만들어낸 객체의 원형이라는 것을 생각해 볼 수 있었습니다.
앞서 객체가 가지고 있는 __proto__
는 객체가 생성 될 때의 조상인 함수의 Prototype Object를 가르킨다고 알 수 있었습니다. 객체 gu
가 leg속성을 직접 가지고 있는 것이 아니기 때문에 leg속성을 찾을 때 까지 상위 프로토 타입을 탐색합니다. 최상위 Prototype Object 까지 도달했는데도 그 속성을 찾지 못하면 undefined를 return 한다고 합니다.
이처럼 연결 고리가 이어져 상속관계를 통하여 상위 프로토 타입으로 연속해서 이어지는 관계를 프로토타입 체인이라고 합니다.
확인해 본 모습입니다.
이런 체인구조로 모든 객체는 Object의 자식이라 불리고 객체는 Object Prototype Object의 속성을 사용할 수 있습니다.
< gu.toString()
> "[object Object]"
< gu.hasOwnProperty()
> false
저번 객체지향의 특징 중에 상속이라는 개념을 알 수 있었습니다. 상속은 불필요한 코드를 줄이고 유지보수를 용이하게 해줍니다. 자바스크립트는 Prototype을 이용하여 상속이라는 개념을 사용합니다. 왜 Prototype을 사용하는지 다시 한번 느낄수 있었습니다.
그럼 마지막으로!
우리가 MDN에서 자료를 찾을 때
Array.prototype.~~
라고 되어있는 것을 무엇을 의미할까요?
Array의 원형에 속성으로 있는 메소드임을 의미하는 것 입니다!
Reference