기본적으로 자바스크립트는 객체지향 프로그래밍을 지원합니다. 단, Java와 다르게 프로토타입 기반의 객체지향 언어입니다. 자바스크립트에서는 this만큼이나 프로토타입에 대한 이해가 반드시 필요합니다. 어찌 보면 가장 어려운 개념일 수도 있지만 이번 포스팅과 다음 포스팅을 통해서 한 번 자세하게 살펴보도록 하겠습니다.
프로토타입 객체
자바스크립트는 클래스가 없습니다. 사실, 하다 보면 느끼겠지만 지원하지 않는다기보단 클래스를 만들어 사용할 수는 있습니다. 또한, ES6부터는 클래스를 지원하고 이는 기존 ES5의 프로토타입 개념을 기반으로 사용하기 편하게 바꾼 Syntatic Sugar입니다.
Java에서는 class를 이용해서 객체를 생성하지만, 자바스크립트에서는 객체 리터럴이나 생성자 함수를 이용해 객체를 생성합니다. 이때, 생성된 객체의 부모 객체를 가리켜 프로토타입 객체라고 합니다.
var obj = {
name : 'BKJang',
age : 25,
sex : 'male'
}
console.log(obj.toString()); //[object Object]
console.dir(obj);
console.dir(obj)
의 결과를 보면 __proto__ : Object
를 볼 수 있을 것입니다. 자바스크립트의 모든 객체는 자신의 프로토타입을 가리키는 [[Prototype]]이라는 숨겨진 프로퍼티를 가집니다.
위의 이미지를 보면 알 수 있듯이 크롬 브라우저에서는 숨겨진 [[Prototype]] 프로퍼티를 __proto__
프로퍼티로 표현하고 있습니다. 즉, obj
객체는 __proto__
프로퍼티로 프로토타입 객체인 Object.prototype를 가리키고 있습니다.
그리고 Object.prototype 객체의 내부를 보면 toString() 메서드가
구현된 것을 볼 수 있습니다. 즉, obj객체는 부모 객체인 Object.prototype객체 내부에 있는 toString() 메서드를
사용했기 때문에, obj
객체 안에 toString() 메서드가
구현이 안 되어있어도 에러가 안 났던 것입니다.
var obj = {
name : 'BKJang',
age : 25,
sex : 'male'
}
console.log(obj.__proto__ === Object.prototype); //true
[[Prototype]] 프로퍼티와 prototype 프로퍼티
여기서부터 [[Prototype]] 프로퍼티를 [[Prototpye]]링크라고 하겠습니다.
//Developer 생성자 함수
function Developer(name, age) {
this.name = name;
this.age = age;
}
//new 객체 생성
var web = new Developer('BKJang', 25);
console.dir(Developer);
console.dir(web);
console.log(Developer.prototype);
/* 출력
{constructor: ƒ}
constructor: ƒ Developer(name, age)
__proto__: Object
*/
console.log(web.__proto__);
/* 출력
{constructor: ƒ}
constructor: ƒ Developer(name, age)
__proto__: Object
*/
console.log(web.prototype); //undefined
console.log(Developer.prototype === web.__proto__); //true
console.log(Developer.__proto__ === Function.prototype); //true (함수 객체의 __proto__([[Prototype]]링크))는 Function.prototype을 가리킨다.
prototype 프로퍼티
- 함수 객체만 가지고 있는 프로퍼티입니다.
- 함수 객체(Developer)를 통해 생성될 객체(web)의 부모 역할을 하는 객체(프로토타입 객체)를 가리킵니다.
[[Prototype]] 링크
- 함수를 포함한 모든 객체가 가지고 있는 프로퍼티입니다.
- 객체의 입장에서 부모인 프로토타입 객체를 가리키며, 함수 객체의 경우 Function.prototype을 가리킵니다. 이는 다음 포스팅에서 이어질 프로토타입 체인에서 자세히 설명할 예정입니다.
constructor 프로퍼티
프로토타입 객체(Prototype Object)는 constructor 프로퍼티를 가집니다. constructor 프로퍼티는 객체 자신을 생성한 객체를 가리킵니다.
function Developer(name) {
this.name = name;
}
var web = new Developer('BKJang');
/* Developer.prototype을 생성한 객체는 Developer 함수 객체 */
console.log(Developer.prototype.constructor === Developer); //true
/* web 객체를 생성한 객체는 Developer 함수 객체 */
console.log(web.constructor === Developer); //true
/* Developer를 생성한 객체는 Function 함수 객체 */
console.log(Developer.constructor === Function); //true
결론
용어가 다 비슷비슷하다 보니 머릿속에 개념이 잘 정리가 안될 수 있기 때문에 마지막으로 정리르 한 번 해보도록 하겠습니다.
- 프로토타입 객체(Prototype Object) : 생성한 객체의 부모 역할을 하는 객체
- 프로토타입 링크([[Prototype]] 링크) : 크롬 브라우저에서는 __proto__로 표현하고 있으며, 부모 역할을 하는 프로토타입 객체를 가리킨다.
- 프로토타입 프로퍼티(Prototype 프로퍼티) : 함수 객체(Developer)만 가지고 있으며, 이 객체를 통해 생성될 객체(web)의 프로토타입 객체를 가리킨다.
- constructor 프로퍼티 : 객체 입장에서 자신을 생성한 객체를 가리킨다.
이를 이미지로 정리하면 다음과 같습니다.
Reference
- 인사이드 자바스크립트 (송형주, 고형준)
'IT > 자바스크립트' 카테고리의 다른 글
[JS] 스코프 (Scope) (0) | 2023.03.13 |
---|---|
[JS] 프로토타입 체인 (Prototype Chain) (0) | 2023.03.08 |
[JS] 함수의 호출과 this (0) | 2023.03.06 |
[JS] 함수의 호출과 arguments객체 (0) | 2023.03.02 |
[JS] 함수의 종류 (0) | 2023.02.28 |
댓글0