자바스크립트는 프로토타입 기반의 객체지향 프로그래밍 언어다.
상태 데이터: 프로퍼티
동작: 메서드
객체지향 프로그래밍의 핵심이다.
어떤 객체의 프로퍼티나 메서드를 다른 객체가 상속받아 그대로 사용할 수 있는 것을 말한다.
자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거한다.
즉, 동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메서드를 중복 소유하는 것을 막을 수 있다.
프로토타입 객체, 줄여서 프로토타입은 상속을 구현하기 위해 사용된다.
프로토타입은 어떤 객체의 부모 객체 역할을 하는 객체로서 다른 객체에 공유 프로퍼티와 메서드를 제공한다.
자식 객체는 부모 객체의 프로퍼티를 자유롭게 사용 가능하지만 부모 객체는 자식 객체의 프로퍼티를 사용할 수 없다.
모든 객체는 [[Prototype]] 내부 슬롯을 가지며 저장되는 프로토타입은 객체 생성 방식에 의해 결정된다.
모든 객체는 하나의 프로토타입을 가지고 모든 프로토타입은 생성자 함수와 연결되어 있다.
[[Prototype]] 내부 슬롯에 직접 접근할 수는 없지만 __proto__ 접근자 프로퍼티를 사용하여 [[Prototype]] 내부 슬롯이 가리키는 프로토타입에 간접적으로 접근할 수 있다.
__proto__ 접근자 프로퍼티는 순환 참조, 즉 무한 루프에 빠지는 것을 방지한다. 하지만 모든 객체가 __proto__ 접근자 프로퍼티를 사용할 수 있는 것은 아니기에 코드 내에서 직접적으로 사용하는 것은 권장하지 않는다. 대신, 프로토타입의 참조를 취득하고 싶거나 교체하고 싶은 경우Object.getPrototypeOf와 Object.setPrototypeOf를 사용하는 것을 권장한다.
그리고 프로토타입은 자신의 constructor 프로퍼티를 통해 생성자 함수에 접근할 수 있고 생성자 함수는 prototype 프로퍼티를 통해 프로토타입에 접근할 수 있다.

// obj 객체를 생성한 생성자 함수는 Object임.
const obj = new Object();
console.log(obj.constructor === Object); // true
// add 함수를 생성한 생성자 함수는 Function임.
const add = new Function ('a', 'b', 'return a+b');
console.log(add.constructor === Function); // true
// 생성자 함수
function Person(name) {
this.name = name;
}
// me 객체를 생성한 생성자 함수는 Person임.
const me = new Person('Lee');
console.log(me.constructor === Person); // true
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성된다.
constructor는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성된다.
빌트인 생성자 함수는 객테가 생성되기 이전에 생성자 함수와 프로토타입은이미 객체화되어 존재한다. 이후 생성자 함수나 리터럴 표기법으로 객체를 생성하면 프로토타입은 생성된 객체 [[Prototype]] 내부 슬롯에 할당된다.
자바스크립트는 객체의 프로퍼티(에서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로피티가 없 다면 (tprototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라 한다. 프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 메커니즘이다.
kry in object
Reflect.has
for (변수선언문 in 객체) {...}
Object.keys/values/entries -> 객체 자신의 고유 프로퍼티 열거