[노란책] 객체지향프로그래밍
객체지향프로그래밍
자바스크립트에서의 객체(Object)는 값을 닮을 수 있는 해시테이블에 불과함 클래스 개념이 없기 때문에 어떤 객체의 값을 복사하는 등의 일을 할 수 없음
프로퍼티 타입
데이터를 어떻게 저장하는 가에 따라 두 가지 프로퍼티 타입이 있다: Data Property 와 Accessor Property 각 프로퍼티 타입별로 내부적으로 정의된 속성값이 있다.
프로퍼티 타입의 속성
Data Property: 값을 직접 저장하는 프로퍼티, 일반적으로 객체의 프로퍼티를 정의하면 Data Property로 지정된다. Accessor Property: getter, setter를 정의하여 값을 저장하는 프로퍼티
두 프로퍼티가 공통적으로 갖는 속성
[[Enumerable]]
: 나열할 수 있는 지, true인 경우, for-in 문에서 표기된다.[[Configurable]]
: 수정 가능한지, 한 번 false로 지정되면 수정할 수 없다.
Data Property만 같고 있는 속성
[[Value]]
: 저장되는 값, 초기값은 undefined[[Writable]]
: 값을 수정할 수 있는 지,
Accessor Property의 경우
[[Get]]
: getter[[Set]]
: setter
프로퍼티 정의하기
리터럴 방식
var obj = {
name: 'hello'
}
Object.defineProperty
Object.defineProperty(obj, 'name', {
value: 'hello',
})
Object.defineProperties(obj, {
name: {
value: 'hello',
},
age: {
set: function(age) { this._age = age; },
get: function() { return this._age; }
}
});
프로퍼티 속성 읽기
Object.getOwnPropertyDescriptor()
객체 생성하기
팩토리 패턴:
- 정의: 함수 내에서 Object 타입의 객체를 생성하여, 프로퍼티/값을 지정한 것
- 한계: 객체가 생성될 때마다 같은 기능을 하는 메서드가 계속 생성된다.
이를 회피하기 위해, 메서드값으로 메서드포인터를 지정해둘 수 있지만, 전역스코프를 어지럽힌다.
instanceOf
로 타입을 구분할 수 없다.
생성자 패턴:
- 정의: new를 사용하여 객체를 생성하는 방식
- instanceof로 타입을 구분할 수 있게 됨
- 내부의 메서드가 여전히 매번 생성된다는 한계가 있음
프로토타입 패턴:
- 정의: 생성자 함수의 프로토타입에 값을 정의하는 방식
- 내부 메서드는 한 번만 생성됨
-
객체에 정의한 값이 참조값일 경우, 인스턴스 간에 공유되는 한계가 있음
- Object.hasOwnProperty(‘propertyName’): 객체의 인스턴스에 직접 정의된 프로퍼티인 경우, true
- ‘propertyName’ in Object: 객체의 프로퍼티인 지, 프로토타입 체인으로 접근할 수 있으면 항상 true
혼합 프로토타입 패턴:
- 생성자 패턴과 프로토타입 패턴을 섞은 것 인스턴스 간에 공유되면 안 되는 값은 생성자에 정의하고, 인스턴스 간에 공유해도 되는 메서드는 프로토타입에 정의한다.
상속
- 객체의 프로토타입이 상속받고자 하는 객체에 접근할 수 있게 한 것
프로토타입 체이닝
- 상속하고자 하는 객체의 인스턴스를 상속받는 함수의 프로토타입으로 지정한다.
- 프로토타입에 지정된 값은 생성된 객체끼리 공유하므로 슈퍼타입의 생성자에 있는 값이 상속받는 객체의 프로토타입에 생성되어 공유하게 된다.
- 슈퍼타입의 생성자에 값을 넣을 수 없다.
- 객체 생성 이후, 프로토타입을 변경한다면 이전에 생성된 객체와의 연결이 끊어진다.
생성자 훔치기 패턴
- 서브타입의 생성자에서 슈퍼타입의 생성자를 호출하여 슈퍼타입의 생성자에 값을 할당할 수 없다.
- 슈퍼타입의 생성자가 2번 호출된다.
- 슈퍼타입에서 정의한 프로퍼티가 서브타입의 프로토타입에 생성됨
프로토타입만 복사해서 연결
- 슈퍼타입의 프로퍼티가 서브타입의 프로토타입에 생성되지 않는다.
- 슈퍼타입의 생성자에서 정의한 것은 인스턴스에만 정의됨
- 공유해야하는 메서드는 프로토타입에서 선언하고
- 공유하지 않아도 되는 메서드는 프로토타입에서 선언한다.