개발하자

Javascript Prototype 최종 정리!!(프로토타입 체인, 다이어그램) 본문

Javascript

Javascript Prototype 최종 정리!!(프로토타입 체인, 다이어그램)

hyesun 2021. 12. 15. 00:02

이 전에 JS Prototype에 대해서 자세하게 학습한 적이 있었다.

 

그때 정리를 해두고 완벽하게 이해를 했다고 생각했는데,,

 

최근에 다시 Prototype에 대해 정리를 하려고 봤더니

 

많이 헤깔렸다!! 

 

그래서 이번에는 블로그에 정리해두고 헤깔릴 때마다 보려고 한다.

 

프로토타입 상속에 대해 자세하게 공부하고 싶다면 이 사이트를 참고하면 좋다!!

https://ko.javascript.info/prototype-inheritance

 

프로토타입 상속

 

ko.javascript.info


Prototype이 무엇일까?

 

상속을 가능하게 하는 자바스크립트 언어의 고유 기능이라고 한 줄 요약을 할 수 있다.

 

class의 extends와 완전히 같지는 않다!!

 

class를 prototype 체인에 연결 하려고 했을 떄 문제가 발생했던 적이 있다.

 

class extends 코드를 보니까 프로토타입체인과 함께 추가적인 코드가 더 있었다.

 

 

 

 

일단 기본적이 키워드를 먼저 정리하고, 동작에 대해서 정리해야겠다.


[[Prototype]], __proto__

 

[[Prototype]] 과 __proto__는 다르다.

 

[[Prototype]] 는 JS의 숨김프로퍼티이다.

 

다른 객체에 대한 참조를 나타낸다

 

__proto__ 는 [[Prototype]]의 getter와 setter 이다.

 

이것만 명확히해도 참조 문서를 이해하기 쉽다.

 


함수의 prototype 프로퍼티

 

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

console.log(Person.prototype.constructor === Person)
//결과:true

 

위 코드 처럼 함수를 생성할 떄 prototype이라는 프로퍼티가 생긴다.

 

이 프로퍼티는 개발자가 특별히 할당하지 않아도 생성된다.

 

그래서 Person.prototype에서 prototype은 [[Prototype]]가 아니다!!

 

그냥 다른 프로퍼티와 마찬가지인 일반 프로퍼티이다.

 

그리고 prototype은 constructor 프로퍼티 하나만 있는 객체를 가리킨다.

 

이 constructor는 함수 자신을 가리킨다.

 

 

prototype 프로퍼티와 constructor프로퍼티를 이용해서 서로 접근 가능하게 돼 있다.

 

 


Person.prototype에 프로퍼티 추가

 

Person.prototype에 walk, eat 함수를 추가했다.

 

Person.prototype에 추가한 함수들은 Person으로 생성하는 인스턴스들이 전부 사용할 수 있다.

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

Person.prototype.walk = function () {
  console.log("working");
};

Person.prototype.eat = function () {
  console.log("eating");
};

 


인스턴스 생성시 [[Prototype]] 할당

 

new 연산자를 사용해서 새로운 객체를 만들 수 있다.

 

이 때 인스턴스의 [[Prototype]]을 Person.prototype로 할당한다.

 

아래의 코드의 결과를 보면 좀 더 명확하게 알 수 있다.

 

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

Person.prototype.walk = function () {
  console.log("working");
};

Person.prototype.eat = function () {
  console.log("eating");
};

const person = new Person("sun", "28");

console.log(person.__proto__ === Person.prototype); //1
console.log(person); //2
person.walk(); //2
person.eat(); //2

 

1번 코드는 person의 [[Prototype]]이 Person.prototype을 가리키고 있다는 것을 의미한다.

 

2번 코드는 Person 함수에 없지만 Person.prototype에

 

추가된 walk, eat이 동작 하는 것을 확인 할 수 있다.

 

코드를 실행해보면 Person 함수 자체에는 eat, walk 함수가 없지만

 

실행이 잘 되는 것을 볼 수 있다.

 

이처럼 인스턴스에서 존재하지 않는 프로퍼티는 [[Prototype]]가 가리키는 객체에서

 

해당 프로퍼티를 찾는다.

 

인스턴스와 [[Prototype]]가 가리키는 객체가 동일한 프로퍼티를 같다면

 

당연하게도 인스턴스의 프로퍼티가 실행된다.

 

 


 

네이티브 프로토타입을 포함한 다이어그램

 

모든 내장 생성자 함수에서 프로토타입이 사용 된다. (Function, Array, Number, Object)

 

그래서 person을 포함한 네이티브 프로토타입 다이어그램을 그려봤다.

 

모든 JS 객체들은 연결된다는 것을 알 수 있다!!

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments