프로토타입
자바스크립트는 프로토타입 기반 언어
프로토타입 기반 언어의 경우 객체를 원형(prototype)으로 삼아 이를 참조해서 상속과 비슷한 효과를 만들어낸다.
const Animal = function(species, birthYear) { this.species = species; this.birthYear = birthYear; } const tiger = new Animal('Siberian', 1234); console.log(tiger); // Animal {species: 'Siberian', birthYear: 1234} console.log(tiger instanceof Animal); // true
- 생성자 함수를 new 연산자와 함께 호출하면
- 생성자에 정의된 내용을 바탕으로 인스턴스가 생성된다.
- 인스턴스에는 자동으로
__proto__
가 부여되고
__proto__
를 이용해서 생성자의 prototype 프로퍼티에 접근할 수 있다.

prototype
다른 클래스 언어와 같이 메서드를 작성하려면 ‘prototype’이 필요하다.
- 만약 생성자 함수 내부에 메서드를 작성한 경우, 모든 인스턴스에 사용할지도 모르는 메서드가 항상 포함되므로 비효율적인 코드가 됨
prototype 객체 내부에는 인스턴스의 메서드가 저장된다.
Animal.prototype.calcAge = function () { console.log(2022 - this.birthYear); } // 메서드 접근 console.log(Animal.prototype); // {calcAge: ƒ, constructor: ƒ} console.log(tiger.__proto__); // {calcAge: ƒ, constructor: ƒ} console.log(Animal.prototype === tiger.__proto__); // true
생성자의 prototype과 인스턴스의
__proto__
는 같은 객체를 가리킨다.__proto__

Animal.prototype.calcAge = function () { console.log(2022 - this.birthYear); } console.log(tiger); // Animal {species: 'Siberian', birthYear: 1234} console.log(tiger.__proto__); // {calcAge: ƒ, constructor: ƒ} tiger.calcAge(); // 788 console.log(tiger.__proto__.calcAge === tiger.calcAge); // true
- tiger라는 인스턴스 내부에는 calcAge 메서드가 없는데 어떻게 정상적으로 실행될까?
- tiger.__proto__ 내부에 메서드가 존재하는데 어떻게 tiger.calcAge()로 메서드가 실행될까?
__proto__
는 생략 가능한 프로퍼티이기 때문이다.자바스크립트 구조를 설계한 브랜든 아이크가 ‘생략 가능한 프로퍼티’ 개념을 만듦

[[Prototype]]의 값은 프로토타입 객체이며 __proto__(accessor property)로 접근할 수 있다. __proto__ 프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf가 호출되어 프로토타입 객체를 반환한다.
Array.protype.map
- 생성자 함수의 prototype에는 메서드가 저장되어 있다.
- 생성자 함수를 바탕으로 생성된 인스턴스 arr로 map 메서드를 사용할 수 있다.
- Array.prototype.map === arr.__proto__.map === arr.map
const arr = [1, 2, 3, 4, 5]; const newArr = arr.map((v) => v + 1); console.log(newArr); // [2, 3, 4, 5, 6]