자바스크립트의 자료형을 보면 숫자, 문자, 논리값, NaN
, undefined
, Symbol
, 객체, 배열 등 원시타입과 그 이외의 타입이 있었습니다.
자바스크립트에서 원시타입 이외의 자료형을 객체라고 하고, 이 객체는 이름과 값을 하나의 쌍으로 묶은 것을 의미합니다.
그 쌍을 property라고 하고 그 property의 이름을 key라고 부릅니다.
예를 들어,
const michel = {
name: "Michael",
age: 25,
color: "blue"
}
michael
이라는 객체에 세개의 properties가 존재하고, name
, age
, color
라는 key안에 값들이 지정되어 저장된 형태입니다. 중괄호 안에 들어있는 정보는 한 묶음으로 봅니다.
위와 같이 객체 리터럴로 객체를 만드는 방법이 가장 흔한 경우입니다. 중괄호 안에 바로 key-value를 쌍으로 직접 넣어주는 방법이지요.
객체 생성자로 생성하는 방법도 있습니다.
function Michael (name, age, color) {
this.name = name;
this.age = age;
this.color = color;
}
const michael = new Michael("Michael", 25, "blue");
또 한 방법으로 Object.create
로 생성하는 방법입니다.
const michael = Object.create(Object.prototype, {
name: {
value: "Michael",
writable: true,
enumerable: true,
configurable: true
},
age: {
value: 20,
writable: true,
enumerable: true,
configurable: true
},
color: {
value: "blue",
writable: true,
enumerable: true,
configurable: true
}
});
이 방법은 ECMAScript 5부터 추가된 방법이며 프로토타입의 상속을 다루는 파트에서 자세하게 다루겠습니다.
그렇다면 프로토타입이란 무엇일까요?
생성자 안에서 this
뒤에 어떤 메서드를 정의하게 되면 그 생성자로 생성한 모든 객체에 똑같은 메서드가 추가됩니다. 같은 메서드를 갖는 객체를 반복적으로 생성하다보면 메모리를 그만큼 소비하게 되어 매우 비효율적이라고 할 수 있습니다.
예를 들어 원의 정보를 갖는 객체를 만든다고 가정해보겠습니다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
this.area = function() {
return Math.PI * this.radius * this.radius
}
}
const c1 = new Circle({x: 0, y: 0}, 2.0);
const c2 = new Circle({x: 0, y: 1}, 3.0);
const c3 = new Circle({x: 1, y: 0}, 1.0);
생성자로 만들어진 c1
, c2
, c3
는 각각의 instance가 똑같은 메서드를 소유하고 있습니다.
이렇게 객체를 새로 만들 경우 메모리 낭비라는 결과로 이어지고 이는 매우 비효율적입니다.
이를 해결하기 위해 프로토타입 이라는 것을 정의하여 사용할 수 있는데, 이는 객체에 적용할 수 있으며 함수 또한 자바스크립트에서는 객체로 보기 때문에 함수에도 적용할 수 있습니다.
위의 코드를 다음과 같이 수정해보겠습니다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
}
Circle.prototype.area = function() {
return Math.PI * this.radius * this.radius
}
const c1 = new Circle({x: 0, y: 0}, 2.0);
const c2 = new Circle({x: 0, y: 1}, 3.0);
const c3 = new Circle({x: 1, y: 0}, 1.0);
console.log(c1.area());
console.log(c2.area());
console.log(c3.area());
이렇게 수정하게 되면 Circle.prototype.area
는 함수 Circle
을 참조하게 되고, c1
, c2
, c3
에 선언된 각각의 생성자는 Circle
을 참조하지 않고 프로토타입 객체를 참조하게 됩니다.
그렇기 때문에 각각의 c1
, c2
, c3
는 함수를 계속적으로 재활용하지 않게 되어 메모리 차지를 줄일 수 있는 것입니다.
이렇게 프로토타입 객체의 프로퍼티를 인스턴스에서 참조할 수 있는 상황을 '인스턴스가 프로토타입 객체를 상속한다' 고 하고, 그 상속 구조는 프로토타입 체인이라는 메커니즘을 바탕으로 구현됩니다.
다음 포스팅에서는 프로토타입의 상속에 대해 더 자세하게 알아보겠습니다.