Javascript에서 Prototype이란, 객체가 공통적으로 가지고 있는 속성 또는 함수들을 묶어놓은 원형이다. 우리가 배열 객체를 선언하고, 객체.toString() 메서드를 사용할 수 있는 것도, 이미 Prototype에 toString() 함수가 정의되어있기 떄문이다. 이것은 클래스 상속의 개념과 일치한다.
모든 객체는 Prototype 이란 을 갖는다.
모든 객체의 가장 최상위 Prototype 은 Object 이다.
객체간 상속의 연결 고리는 Prototype Chain 으로 연결되어있다.
Prototype은 외부에서 직접적으로 접근할 수 없다.
Prototype에 접근하기 위해서는 아래와 같은 속성이나 메서드를 사용해야 한다.
Copy __proto__;
Object.getPrototypeOf();
Object.setPrototypeOf();
생성자함수.prototype;
아래의 화면은 브라우저에서 콘솔을 이용하여 프로토타입의 존재를 확인한 것이다.
프로토타입 디스크립터(Prototype Descripter)
프로토타입 디스크립터는 선언한 객체를 어떻게 사용할 수 있는지에 대한 정보를 보여준다. 어떤 객체를 선언했을 때 해당 객체의 값이 뭐고, 값을 수정할 수 있는지 여부, 순회할 수 있는지 여부 등등에 대한 정보를 가지고 있는 것이 프로토타입 디스크립터이다. 아래의 코드를 보고 살펴보자.
Copy const obj = { a: '1', b: '2' };
console.log(Object.getOwnPropertyDescriptors(obj));
//{
// a: { value: '1', writable: true, enumerable: true, configurable: true },
// b: { value: '2', writable: true, enumerable: true, configurable: true }
//}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'));
// { value: '1', writable: true, enumerable: true, configurable: true }
obj 객체의 value 값은 1 (value)
obj 는 순회할 수 있음 (enumerable)
키와 값을 수정할 수 있음 (configurable)
디스크립터의 속성을 변경할 수 있다.
Copy const obj = { a: '1', b: '2' };
Object.defineProperty(obj, 'a', {
writable: false,
});
obj.a = '2';
console.log(obj); // { a: '1', b: '2' }
오브젝트의 불변성 조정
Object 가 가지고 있는 아래의 함수를 사용하여 객체의 불변성을 강제로 조정할 수 있다.
Object.freeze()
단, 오브젝트 안에 있는 오브젝트는 위의 모든 변경이 가능하다.
Object.isFrozen() 함수를 이용하여 freeze 여부를 확인할 수 있다.
Copy const obj = {
id: 1,
name: 'test',
};
const innerObj = {
id: 1,
name: 'innterTest',
};
obj.inner = innerObj;
console.log(obj);
// { id: 1, name: 'test', inner: { id: 1, name: 'innterTest' } }
Object.freeze(obj);
obj.name = 'test1';
// console.log(obj); // { id: 1, name: 'test' }
obj.inner.name = 'innterTest1';
console.log(obj);
// { id: 1, name: 'test', inner: { id: 1, name: 'innterTest1' } }
Object.seal()
Object.isSealed() 함수를 이용하여 seal 여부를 확인할 수 있다.
Copy const obj = {
id: 1,
name: 'test',
};
Object.seal(obj);
console.log(Object.isSealed(obj));
// true
obj.name = 'test111';
console.log(obj);
// { id: 1, name: 'test111' }
obj.age = 20;
console.log(obj);
// { id: 1, name: 'test111' }
delete obj.age;
console.log(obj);
// { id: 1, name: 'test111' }
Object.preventExtensions()
Copy const obj = { id: 1, name: 'test' };
console.log(obj);
// { id: 1, name: 'test' }
console.log(Object.isExtensible(obj));
// true
Object.preventExtensions(obj);
console.log(Object.isExtensible(obj));
// false
obj.name = 'test111';
console.log(obj);
// { id: 1, name: 'test111' }
delete obj.name;
console.log(obj);
// { id: 1 }
obj.age = 20;
console.log(obj);
// { id: 1 }