prototype

ou·2024년 1월 16일
0

basic

목록 보기
1/24

Prototype (프로토타입) 이란

프로토타입은 해당 객체의 원형이 되는 객체로, 다른 객체에서 상속된 속성 및 메서드를 포함할 수 있습니다.

prototype based language라 불릴만큼
prototype은 자바스크립트를 지탱하는 기반
자바스크립트 동작 원리를 이해하기 위해서 prototype의 개념을 잘 이해하고 있어야함
OOP 프로그래밍의 상속화를 구현하는데 사용

자바스크립트 모든 객체는 자신의 부모 역할을 하는 객체와 연결돼있다. 이것은 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티, 메소드를 상속받아 사용할 수 있다.
이 때, 부모 객체를 Prototype Object(프로토타입 객체) 또는 Prototype(프로토타입)이라고 한다.

ECMAScript spec에서 자바스크립트 모든 객체는 [[Prototype]]이라는 인터널 슬롯(interner slot)을 가짐.
[[Prototype]] 의 값은 Prototype Object(프로토타입 객체)이며 __proto__ 프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf()가 호출돼 Prototype Object(프로토타입 객체)를 반환.

객체를 생성할 때 프로토타입은 결정되며, 결정된 프로토타입 객체는 다른 객체로 변경할 수 있다. 부모 객체은 프로토타입을 동적으로 변경 할 수 있다는 것.

[[Prototype]] vs prototype 프로퍼티

모든 객체는 자신의 프로토타입 객체를 가리키는 [[Prototype]] 인터널 슬롯을 가짐.
함수도 객체이므로 [[Prototype]]인터널 슬롯을 가진다. 함수 객체는 일반 객체와는 달리 prototype 프로퍼티도 있음.
prototype프로퍼티와 [[Prototype]]은 다르므로 주의

  • [[Prototype]]
    1.모든 객체가 가지고 있는 인터널 슬롯
    2.객체 입장에서 자신의 부모인 Prototype Object(프로토타입 객체)를 가리킴.
    예를 들어 함수 객체일 경우 Function.prototype을 가리킴
  • prototype 프로퍼티
    1.객체 중 함수 객체만 가지고 있는 프로퍼티
    2.함수 객체가 생성자로 사용될 때, 생성될 객체의 부모 역할을 하는 Prototype Object(프로토타입 객체)를 가리킴.

Constructor

모든 객체는 자신의 prototype으로부터 constructor 속성을 상속
즉, 자신을 생성한 객체를 가리킴

function Carrot(weight){
	this.weight = weight;
}
const carrot1 = new Carrot(1);

//carrot1을 생성한 객체는 Carrot이다.
carrot1.constructor == Carrot; //true

//carrot1의 Prototype Object(프르토타입 객체)는 Carrot의 prototype 프로퍼티
carrot1.__proto__ == Object.getPrototypeOf(carrot1) == Carrot.prototype; //true

//함수 객체 Carrot의 contructor, 즉 Carrot을 생성한 객체는 Function이다
Carrot.constructor == Function //true

//그리고 함수 객체 Carrot의 Prototype Object(프로토타입 객체)는 Function.prototype이다.
Object.getPrototypeOf(Carrot) == Function.prototype; //true
__proto__ 는 ES6(ECMAScript2015) 이후 Object.getPropertyOf()로 사용하는 것을 권장
prototype 대신 Class, extends 를 사용하는 것 권장

Prototype chain

객체의 프로퍼티나 메소드에 접근할 때 해당 객체에서 찾을 수 없으면, 내부적으로 Object.getPrototypeOf()를 이용해 부모를 찾아가서 가져오고 없으면 또 부모로가고 찾을때까지 가다가 Object.getPrototypeOf()의 결과가 null일 때 까지 찾지 못하면 undefined를 return한다.

function ParentOfParentOfParent(){
	this.name = "부모의부모의부모";
}
function ParentOfParent(){
	this.age = "부모의부모";
}
function Parent(){
	this.gender = "부모"
}
function Child(){
	this.key = "차일드";
}
//Child의 Prototype Object(프로토타입 객체)를 Parent로 지정
Object.setPrototypeOf(Child.prototype, Parent.prototype);

//Parent의 Prototype Object(프로토타입 객체)를 ParentOfParent로 지정
Object.setPrototypeOf(Parent.prototype, ParentOfParent.prototype);

//ParentOfParent의 Prototype Object(프로토타입 객체)를 ParentOfParentOfParent로 지정
Object.setPrototypeOf(ParentOfParent.prototype, ParentOfParentOfParent.prototype);

const a = new Child();
console.log(a.name) //"부모의부모의부모";

Method overriding

자식이 부모의 메서드를 사용하지 않고 덮어쓰는 경우

Property shadowing

자식이 부모의 프로퍼티를 사용하지 않고 덮어쓰는 경우

이 글을 마무리하며

OOP에 대해 쓰려다가 prototype을 먼저 정리하고 가야겠다는 생각이 들어서 prototype 정리로 빠졌다. 다음 글은 OOP에 대해 쓸 예정이다.
지금까지 썼던 글 중 가장 오랜 시간 이해하려고 애썼다.
여태 '참 모르고 써왔구나' 라는 생각이 들며 되돌아보게 된다.

참고자료
https://poiemaweb.com/js-prototype
https://developer.mozilla.org/ko/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

profile
경험을 현명하게 사용한다면, 어떤 일도 시간 낭비는 아니다.

0개의 댓글

관련 채용 정보