Prototype

Dongwon Ahn·2024년 3월 2일
0

JS & TS 학습

목록 보기
6/7

프로토타입??

자바스크립트는 프로토타입 기반의 언어입니다. 자바스크립트에서 모든 객체는 반드시 부모 객체를 가지며, 이 부모 객체를 프로토타입 이라고 합니다. 그리고 자식 객체는 __proto__ 접근자를 통해 부모 객체, 즉 자신의 프로토타입에 접근할 수 있습니다.

그럼 프로토타입이 객체의 원형이라고 부르는 이유는 무엇일까요?


위 예제에서 arr와 obj 두 변수가 includeshasOwnProperty 메소드를 사용할 수 있는 이유는 무엇일까요?
자바스크립트에서 배열와 object 자료형에 위 메소드를 쓸 수 있게 처리를 해놓았기 때문입니다. 상속이라는 개념을 통해서 입니다. 이를 확인해보기 위해서 위에서 이야기한__proto__ 접근자를 통해서 상속된 부모 객체를 확인할 수 있습니다.
또한 각각 자바스크립트에서 미리 만들어놓은 Array와 Object를 상속받고 있는 것을 알 수 있습니다.

프로토타입 체이닝

위 예제 처럼 자바스크립트의 객체는 부모 객체를 __proto__에 상속을 받습니다. 그렇기 때문에 obj의 hasOwnProperty 메소드는 obj의 부모 객체의 메소드를 사용한 것입니다.
이렇듯 자신의 속성에 없으면 부모 객체를 탐색하는 과정을 프로토타입 체이닝이라고 합니다.

프로토타입 체이닝은 순환참조를 허락하지 않으며, __proto__는 객체와 null만 받을 수 있습니다. 순환 참조가 발생하면 무한 루프나 스택 오버플로우와 같은 문제가 발생할 수 있기 때문에 이를 금지합니다.
__proto__ 속성은 객체나 null만을 값으로 가질 수 있으며, null은 프로토타입 체인의 끝을 나타냅니다.

또한 proto 속성이 단일 객체 참조만을 가질 수 있기 때문에, 다른 클래스 기반 언어에서 볼 수 있는 전통적인 다중 상속을 지원하지 않습니다. Javascript에서는 다중 상속을 직접적으로 구현할 수 없으며, 여러 객체의 속성이나 메소드를 상속 받고 싶을때는 다른 방법(ex. MIXIN)을 사용해야 합니다.

for ... in

for ... in은 상속된 부모 객체의 속성도 순회 대상에 포함합니다.
순회 대상에서 제외하고 싶다면 hasOwnProperty(key)를 이용해야 합니다.

const animal = {
  eats: true
};
const rabbit = {
  jumps: true,
  __proto__: animal
};
// Object.keys
console.log(Object.keys(rabbit)); // jumps

// for..in
for(const prop in rabbit) {
  console.log("자신과 부모의 속성이 나옴", prop); // jumps, eats
}
for(const prop in rabbit) {
  const isOwn = rabbit.hasOwnProperty(prop);
  if (isOwn) {
    console.log(`객체 자신의 속성: ${prop}`);
  } else {
  	console.log(`상속된 부모 객체의 속성: ${prop}`);
  }  
}

원시타입과 프로토타입

자바스크립트의 모든 것이 객체이지만, 원시 데이터 타입(primitive data types)은 객체가 아닙니다. 그럼에도 불구하고, 자바스크립트는 이 원시 값을 필요에 따라 객체처럼 다룰 수 있게 해주는 래퍼(wrapper) 객체를 제공합니다. 그렇기 때문에 string 타입에서 at와 같은 메소드를 사용할 수 있습니다.

원시 데이터 타입은 객체와 아래와 같은 차이점이 있습니다.

  • 원시 타입은 불변(immutable)입니다. 즉, 원시 타입의 값을 변경할 수 없으며, 값을 변경하려고 하면 새로운 원시 값을 생성해야 합니다.
  • 원시 타입은 스택 메모리에 저장되며, 객체는 힙 메모리에 저장됩니다.
  • 원시 타입의 값은 값 자체로 비교되며, 객체는 메모리 내의 주소로 비교됩니다

참조
https://ko.javascript.info/
https://developer.mozilla.org/en-US/docs/Glossary/Primitive

profile
Typescript를 통해 풀스택 개발을 진행하고 있습니다.

0개의 댓글