Frontend/JS.info 정리

Prototype - 함수의 prototype 프로퍼티

Creative_Lee 2022. 6. 17. 16:39

1. 함수의 prototype 프로퍼티와 인스턴스의 특징

생성자 함수를 사용해 객체를 생성했을 때와 리터럴 방식으로 객체를 생성했을 때

프로토타입의 동작 방식이 다릅니다.

 

생성자 함수의 new 연산자로 만든 객체(인스턴스)의 [[Prototype]] 은

생성자 함수의 prototype 프로퍼티를 참조합니다.

 

prototype은 생성자 함수의(F)의 '일반 프로퍼티'입니다.  (ex. F.prototype)

let animal = {
  walk: true,
}

function Human(name) {
  this.name = name
}

Human.prototype = animal

let human1 = new Human('Bob')

console.log(human1.walk) // true

위 코드에서  Human.prototype = animal 로 인해

생성자 함수 Human으로 만들어진 인스턴스 human1 은 [[Prototype]] 으로 animal 객체를 참조합니다.


생성자 함수로 인스턴스를 생성한 후에

생성자 함수의 prototype 프로퍼티 값이 바뀌면,  ex) F.prototype = another object

이후 생성자 함수로 생성되는 인스턴스들의 [[Prototype]]은 바뀐 prototype 값이 됩니다. 


2. 함수의 prototype 프로퍼티 기본값과 constructor 프로퍼티

모든 함수는 기본적으로 prototype 프로퍼티를 갖습니다.

 

함수의 prototype 프로퍼티 기본값은

함수 자신을 가리키는 constructor 프로퍼티 하나만 있는 객체를 가리킵니다.

 ex) F.prototype = { constructor : F }

 

function Human(name) {
  this.name = name
}

console.log( Human.prototype.constructor == Human ) // true

3. 생성자 함수와 인스턴스 연관지어 개념 정리

생성자 함수(F) 의  prototype 프로퍼티는 기본적으로 

{ constructor : F } 입니다.

또한 

new 연산자로 만든 인스턴스의 [[Prototype]]은

생성자 함수(F) 의 prototype 프로퍼티를 참조합니다.

 

 생성된 인스턴스의 [[Prototype]]은 { constructor : F }  입니다.

function Human(name) {
  this.name = name
}

let human1 = new Human('Bob') // human1 인스턴스는 {constructor : Human} 를 상속받음.

let human2 = new human1.constructor('God') // 상속받은 생성자 함수를 사용하여 또다른 인스턴스를 생성.

console.log(human2) // Human { name : 'God' }

이러한 원리로

모든 인스턴스에서 constructor 프로퍼티, 즉 생성자 함수를 상속받아 사용할 수 있습니다.


4. 보장되지 않는 constructor

만약 생성자 함수를 만든 후 임의의 값으로 prototype 프로퍼티를 수정할 때에는 주의해야 합니다.

function Human() {}

Human.prototype = {
  think : true
}

let human1 = new Human()

console.log(human1.constructor == Human) // false

 

생성자 함수의 prototype 기본값 대신 새로운 값을 할당하면,

당연하게도 인스턴스에는 constructor가 없습니다.


이런 상황을 방지하고 constructor의 기본 성질을 활용하기 위해서는

위 코드처럼 prototype 자체의 값을 바꾸는게 아니라,

prototype의 기본값에 프로퍼티를 추가해야 합니다.

function Human() {}

Human.prototype.think = true

let human1 = new Human()

console.log(human1.constructor === Human) // true
console.log(human1.think) // true

let human2 = new human1.constructor()

console.log(human2.constructor === Human) // true
console.log(human2.think) // true

요약.

1. 모든 생성자 함수는 prototype 프로퍼티를 가진다.

2. prototype 프로퍼티는 기본값으로 { constructor : 생성자 함수 }  이다.

3. 생성자 함수로 만들어진 인스턴스의 [[Prototype]]은 prototype 값이다.

4. 즉  인스턴스의 프로토타입은 { constructor : 생성자 함수 } 이다.

5. new F() 이 호출될 때, 인스턴스의 [[Prototype]]을 설정한다.

6. 참 직관적이다!

    (인스턴스의 생성자(constructor)는 생성자 함수이고, 인스턴스는 생성자 함수의 prototype 객체를 상속받는다.

 

 

기본이 중요하다!