자바스크립트는 프로토타입 기반의 객체지향 프로그래밍 언어다.
클래스
es6에서 클래스가 도입되었다. 클래스도 함수이며, 기존 프로토타입 기반 패턴의 문법적 설탕이라고 볼 수 있다.
클래스는 생성자 함수보다 엄격하며 생성자 함수에서는 제공하지 않는 기능도 제공한다.
__proto__접근자 프로퍼티
모든 객체는 proto 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.
내부 슬롯은 프로퍼티가 아니며 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하기는 한다.
proto 접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다.
Object.protytpe을 상속받지 않는 객체를 생성할 수또 있기 때문에 proto 접근자 프로퍼티를 사용할 수 없는 경우가 있다.
따라서 proto 접근자 프로퍼티 대신 참조를 취득하고 싶은 경우에는 Object.getPrototypeOf 메서드를 사용하고, 프토토타입을 교체하고 싶은 경우에는 Object.setPrototypeOf 메서드를 사용할 것을 권장한다.
함수 객체의 prototype 프로퍼티
함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.
모든 객체가 가지고 있는(엄밀히 말하면 Object.prototype으로부터 상속받은) proto 접근자 프로퍼티와 함수 객체만이 가지고 있는 protytype 프로퍼티는 결국 동일한 프로토타입을 가리킨다. 하지만 프로퍼티를 사용하는 주체가 다르다.
구분 소유 값 사용 주체 사용 목적
proto 접근자 프로퍼티 | 모든 객체 | 프로토타입의 참조 | 모든 객체 | 객체가 자신의 프로토타입에 접근 또는 교체하기 위해 사용 |
prototype 프로퍼티 | constructor | 프로토타입의 참조 | 생성자 함수 | 생성자 함수가 자신이 생성할 객체(인스턴스)의 프로토타입을 할당하기 위해 사용 |
프로토타입 체인
자바스크립트는 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라 한다. 프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 매커니즘이다.
Object.prototype을 프로토타입 체인의 종점(end of prototype chain)이라 한다. Object.prototype의 프로토타입, 즉 [[Prototype]] 내부 슬롯의 값은 null이다.
프로토타입 체인은 상속과 프로퍼티 검색을 위한 매커니즘.
스코프 체인은 식별자 검색을 위한 매커니즘.
오버라이딩과 프로퍼티 섀도잉
프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 프로토타입 체인을 따라 프로토타입 프로퍼티를 검색하여 프로토타입 프로퍼티를 덮어쓰는 것이 아니라 인스턴스 프로퍼티로 추가한다. 이때 인스턴스 메서드는 프로토타입 메서드를 오버라이딩 했고 프로토타입 메서드는 가려진다. 이처럼 상속 관계에 의해 프로퍼티가 가려지는 현상을 프로퍼티 섀도잉이라한다.
instanceof 연산자
우변의 생성자 함수의 prototype에 바인딩된 객체가 좌변의 객체의 프로토타입 체인 상에 존재하면 true로 평가되고, 그렇지 않은 경우에는 false로 평가된다.
생성자 함수의 prototype에 바인딩된 객체가 프로토타입 체인 상에 존재하는지 확인한다.
function Person(name) {
this.name;
}
const me = new Person('Lee');
console.log(me instanceof Person); // true
console.log(me instanceof Object); // true
for ... in 문
객체의 모든 프로퍼티를 순위하며 열거하려면 for...in문을 사용한다.
for...in 문은 순회 대상 객체의 프로퍼티뿐만 아니라 상속받은 프로토타입의 프로퍼티까지 열거한다.
for...in 문은 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중에서 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티를 순회하며 열거한다.
상속받은 프로퍼티는 제외하고 객체 자신의 프로퍼티만 열거하려면 Object.prototype.hasOwnProperty 메서드를 사용하여 객체 자신의 프로퍼티인지 확인해야 한다.
'Web > JavaScript' 카테고리의 다른 글
렉시컬 스코프 (0) | 2022.04.08 |
---|---|
라인 피드와 캐리지 리턴 (0) | 2022.04.07 |
자주 사용하는 정규표현식 [ javascript ] (0) | 2021.09.08 |
&&와 || 연산자 (0) | 2021.07.19 |
하나만 true/truthy인지 구분하기 js (0) | 2021.07.19 |