프로토타입

hoonnotes

그럼 class는 뭔데요?

객체지향 언어의 class와는 다르다

프로토타입으로 구현하선 상속을 조금 더 쉽게 해주는 도우미 역할!

프로토타입을 활용한 상속

function Circle(radius) {
  this.radius = radius;
  this.getArea = function () {
    return Math.PI * this.radius ** 2;
  };
}

const circle1 = new Circle(10);
const circle2 = new Circle(40);

Circle

Circle2

Circle1

radius

10

getArea

f ()

radius

40

getArea

f ()

프로토타입을 활용한 상속

function Circle(radius) {
  this.radius = radius;
}

Circle.prototype.getArea = function () {
  return Math.PI * this.radius ** 2;
};

const circle1 = new Circle(10);
const circle2 = new Circle(40);

Circle

Circle2

Circle1

radius

10

radius

40

getArea

f ()

Circle.prototype

prototype

Text

getArea

getArea

그래서 프로토타입이 뭔데?

  • 객체간 상속을 구현하기 위한 기능
  • 프로토타입
    • 원래의 형태 또는 전형적인 예
    • 기초 또는 표준
  • [[Prototype]]
    • 모든 객체들이 갖고있는 슬롯
    • 자기 자신의 프로토타입이 되는 객체를 가리킨다
    • 가장 마지막엔 null !

 

그래서 프로토타입이 뭔데?

생성자 함수

생성자함수.prototype

객체 인스턴스

prototype

constructor

state

method

__proto__

__proto__

__proto__

__proto__

const person = { name: "hoon" };
const empty = {};

empty.__proto__ = person;

console.log(empty) // {}

console.log(empty.name) // hoon

__proto__

const person = { name: "hoon" };

console.log(person.hasOwnProperty("__proto__")); // false

console.log(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"));
// {enumerable: false, configurable: true, get: ƒ, set: ƒ}

console.log({}.__proto__ === Object.prototype); // true

Object.prototype

  • 자바스크립트의 모든것은 객체!
  • 생성자함수: 객체를 만들기 위해 사용
  • 생성자함수는 첫 낱말이 대문자이다
    • Object 도 첫 낱말이 대문자이다 
  • 자바스크립트에서 기본적으로 제공
  • 생성자 함수의 프로퍼티로, 모든 객체들의 원본이 되어주는 프로토타입!

Why __proto__ ? 

const chicken = {};
const egg = {};

chicken.__proto__ = egg;
egg.__proto__ = chicken;

VM4414:5 Uncaught TypeError: Cyclic __proto__ value
    at Object.set __proto__ [as __proto__] (<anonymous>)
    at <anonymous>:5:15

chicken

egg

Why __proto__ ? 

const chicken = {};
const egg = {};

chicken.__proto__ = egg;
egg.__proto__ = chicken;

VM4414:5 Uncaught TypeError: Cyclic __proto__ value
    at Object.set __proto__ [as __proto__] (<anonymous>)
    at <anonymous>:5:15

chicken

egg

don't use __proto__ !

const sample = Object.create(null) 
console.log(sample.__proto__); // undefined
console.log(Object.getPrototypeOf(sample)); // null
  • 어떤 객체는 __proto__ 사용이 불가능 
  • getPrototypeOf 를 사용하는게 적절

don't use __proto__ !

const sample = Object.create(null) 
console.log(sample.__proto__); // undefined
console.log(Object.getPrototypeOf(sample)); // null
  • 어떤 객체는 __proto__ 사용이 불가능 
  • getPrototypeOf 를 사용하는게 적절

don't use __proto__ !

const chicken = { sound: "꼬꼬" };
const egg = {};

console.log(Object.getPrototypeOf(egg));
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

Object.setPrototypeOf(egg, chicken);

console.log(egg.sound);
// 꼬꼬
  • getPrototypeOf 로 proto 확인 
  • setPrototypeOf 로 proto 설정

함수의 prototype

  • 함수 객체만 갖고있는 프로퍼티
    • Call 
    • Constructor
  • 함수 객체만 갖고있는 prototype
    • 생성자 함수가 생성할 인스턴스의 프로토타입

함수의 prototype

(function () {}.hasOwnProperty("prototype")); // true

({}.hasOwnProperty("prototype")); // false
  • 일반 객체는 prototype 프로퍼티가 존재하지 않는다
  • 함수는 prototype 프로퍼티가 존재한다
  • 함수의 prototype은 인스턴스의 프로토타입을 가리킨다
  • non-constructor 함수는 prototype이 존재하지 않는다
    • arrow function
    • methods

함수의 prototype

const Person = (name) => {
  this.name = name;
};

console.log(Person.hasOwnProperty('prototype')); // false
console.log(Person.prototype); // undefined


const sample = {
  method() {}
}

console.log(sample.method.hasOwnProperty('prototype')); // false
console.log(sample.method.prototype); // undefined

함수의 prototype

함수의 prototype

function Person(name) {
  this.name = name;
}

const hoon = new Person("hoon");
console.log(Person.prototype === hoon.__proto__);

Person 생성자 함수

prototype

__proto__

Person.prototype

constructor

__proto__

Function.prototype

Object.prototype

hoon (인스턴스)

name

__proto__

hoon

new 키워드로 생성

prototype의 constructor 함수 실행

Person

프로토타입의 constructor

function Person(name) {
  this.name = name;
}

const hoon = new Person("hoon");
console.log(Person === hoon.constructor);

생성자 함수로 만든 객체의 프로토타입

const obj = new Object();
console.log(obj.constructor === Object);

const func = new Function();
console.log(func.constructor === Function);

function Person() {}
const hoon = new Person();
console.log(hoon.constructor === Person);

리터럴로 만든 객체의 프로토타입

const obj = {};
console.log(obj.constructor === Object);

const func = function () {};
console.log(func.constructor === Function);

const arr = [];
console.log(arr.constructor === Array);

리터럴로 만든 객체의 프로토타입

추상연산

const obj = new Object();
console.log(obj); // {}

class Sample extends Object {}
console.log(new Sample()); // Sample {}

const nums = new Object(1005);
console.log(nums); // [Number: 1005]

const strings = new Object("hoon");
console.log(strings); // [String: 'hoon']

Object 생성자 함수는,

  • 인자값이 없으면 빈 객체를
  • 숫자를 받아오면 숫자 객체를
  • 문자열을 받아오면 문자열 객체를
  • 클래스를 받아오면 클래스 객체를

생성한다!

추상연산

const name = new String("hoon");
console.log(name.__proto__ === String.prototype);

const obj = new Object();
console.log(obj.__proto__ === Object.prototype);

const nums = new Object(123);
console.log(nums.__proto__ === Number.prototype);

추상연산

추상연산

결론!

10-1. 프로토타입

By hoonnotes

10-1. 프로토타입

  • 71