프로토타입

  • 객체의 부모역할을 하는 객체
  • 자식 객체에게 프로퍼티와 메서드를 상속

프로토타입 사용이유

  • 생성자 함수로 인스턴스 생성할 때, 중복 프로퍼티, 메서드 생성해서 자원이 낭비됨
  • 만약 10개의 인스턴스 생성하면 동일한 메서드가 10개 생성되는 셈
  • 프로토타입을 활용해 상속하여 불필요한 중복 제거 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 생성자 함수로 사용한 경우 >> 메서드 중복되어 자원낭비
function Circler(radius) {
    this.area = radius;
    this.getArea = function() {
        return Math.PI * this.radius ** 2;
    }
}
 
// 인스턴스 2개 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);
 
// 동일한 역할을 하는 메소드지만, 각각 인스턴스가 소유해서 자원이 낭비
console.log(circle1.getArea === circle2.getArea); // false
 
 
// prototype 사용할 경우 >> 상속통해 중복제거 가능
function Circle(radius) {
    this.area = radius;
}
Circle.prototype.getArea = function() {
    return Math.PI * this.radius ** 2;
}
 
// 인스턴스 2개 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);
 
// 하나의 메서드를 공유
console.log(circle1.getArea === circle2.getArea); // true
cs

프로토타입 체인

  • 프로토타입이 한 방향으로 연결되어있는 상속구조
  • 정확히 말하면 단방향 링크드 리스트
  • 객체의 프로퍼티, 메서드에 접근할때 없으면, 프로토타입 체인 따라서 부모 프로퍼티 확인
  • 프로토타입 체인의 최상위 객체 : Object.prototype
  • 모든 객체는 Object.prototype의 프로퍼티와 메서드 사용 가능

프로토타입, 생성자 함수 관계

  • 프로토타입
    • 객체의 __proto__로 접근 가능
      • __proto__ : 프로토타입에 접근하는 내부 접근자, __proto__ 참조
    • constructor 메서드를 가짐 : 생성자 함수
    • __proto__ 프로퍼티 : Object.prototype
  • 생성자 함수
    • prototype 프로퍼티 : Prototype 객체
    • __proto__ 프로퍼티 : Function.prototype
    • 프로토타입 생성 시점 : 생성자 함수 생성될때 생성

오버라이딩, 프로퍼티 섀도잉

  • 오버라이딩 : 프로토타입에 정의된 프로퍼티, 메서드를 객체에서 새롭게 추가
    • 객체에 추가된 프로퍼티 호출됨
    • 프로토타입 프로퍼티를 덮어쓰는것이 아닌, 객체에 새로운 프로퍼티가 추가
  • 프로퍼티 섀도잉 : 객체에 새로운 프로퍼티, 메서드 추가할때, 프로토타입의 것이 가려지는 현상

출처

  • 모던 자바스크립트 Deep Dive, Ch 19

__proto__ 란?

  • 객체에서 __proto__를 통해 프로토타입에 접근 가능
  • 프로토타입은 내부슬롯 [[Prototype]]으로 존재
  • __proto__ : 접근자 프로퍼티로 [[Prototype]]에 접근
    • 접근자 프로퍼티 : 다른 프로퍼티나 내부슬롯을 읽거나 저장할때 사용
  • 사용하는 이유
    • 서로 프로토타입을 참조해서 프로토타입 체인이 꼬여버리는 현상을 방지하기 위해
    • 프로토타입 검색할때 무한 루프에 빠져버리게됨
    • 접근자 프로퍼티 내에서 서로를 참조하는지 체크
  • 직접 사용하는 것은 권장되지 않음
    • Object.getPrototypeOf 사용 : 프로토타입 가져올때
    • Object.setPrototypeOf 사용 : 프로토타입 지정할때
    • 이유 : 모든 객체가 __proto__를 가지고 있지 않음
      • __proto__는 Object.prototype의 접근자 프로퍼티
      • Object.prototype을 상속받지 않을경우 사용 불가능
      • 예시 : null을 상속받아 생성한 객체는 사용 불가

출처

  • 모던 자바스크립트 Deep Dive, Ch 19

직접상속

  • 프로토타입을 지정해서, 프로토타입을 상속한 객체를 생성
  • Object.create
    • 첫번째 매개변수 : 프로토타입
    • 두번째 매개변수 : 생성할 객체의 프로퍼티 키와 디스크립터 객체 전달
  • 프로퍼티 정의가 번거로움
  • 객체 내부에서 proto 설정
    • 프로퍼티 쉽게 설정 가능
1
2
3
4
5
6
7
8
9
10
11
12
// 직접상속 : Object.create
const obj = Object.create(Object.prototype, {
    x : {value:1, writable: true, enumerable : true, configurable: true}
})
 
// 직접상속 : 객체 내부 __proto__
const myProto = { x : 10 };
const obj = {
    y: 20,
    __proto__ : myProto
};
 
cs

출처

  • 모던 자바스크립트 Deep Dive, Ch 19

+ Recent posts