프로토타입

KHW·2021년 8월 7일
1

Javascript 지식쌓기

목록 보기
67/95

설명 내용

  1. 객체
  2. 생성자 함수 (프로토타입 사용 X)
  3. 생성자 함수 (프로토타입 사용 O)
  4. 클래스

1. 객체

const khw = {
  name: "khw",
  address: "seoul",
};

const msk = {
  name: "msk",
  address: "seoul",
};

const heesu = {
  name: "heesu",
  address: "seoul",
};

간단하게 나타낼 수 있다.


2. 생성자 함수 (프로토타입 사용 X)

function Person(name, address) {
  this.name = name;
  this.address = address;

  this.getInformation = function () {
    console.log(`${this.name} ${this.address}`);
  };
}

const khw = new Person("khw", "seoul");		
const msk = new Person("msk", "busan");		
const heesu = new Person("heesu", "pohang");	

console.log(khw);	//{name: "khw", address: "seoul", getInformation: ƒ}
console.log(msk);	//{name: "msk", address: "busan", getInformation: ƒ}
console.log(heesu);	//{name: "heesu", address: "pohang", getInformation: ƒ}

이때 매번 같은 함수를 객체에 중복해서 각각 담으면 메모리 낭비가 일어난다.


3. 생성자 함수 (프로토타입 사용 O)

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

Person.prototype.getInformation = function () {
  console.log(`${this.name} ${this.address}`);
};

const khw = new Person("khw", "seoul");
const msk = new Person("msk", "busan");
const heesu = new Person("heesu", "pohang");

console.log(khw);	//Person {name: "khw", address: "seoul"}
console.log(msk);	//Person {name: "msk", address: "busan"}
console.log(heesu);	//Person {name: "heesu", address: "pohang"}

console.log(khw.__proto__);		//{getInformation: ƒ, constructor: ƒ}
console.log(msk.__proto__);		//{getInformation: ƒ, constructor: ƒ}
console.log(heesu.__proto__);		//{getInformation: ƒ, constructor: ƒ}

2.내용과는 다르게 객체 자체가 해당 getInformation함수를 포함하지 않고 __proto__에 저장되어 메모리 낭비를 줄인다.


Prototype vs __proto__ vs constructor

prototype은 간단하게 함수에서 접근하는 부모 객체이고
__proto__는 class를 통해 만들어진 객체에서 접근하는 부모 객체라고 생각한다.
constructor는 prototype과 반대로 부모에서 함수로 접근하는 것이다.

  • Person.prototype.getInformation를 통해 부모객체에 getInformation을 추가 할 수 있고

  • Person 함수를 통해 만들어진 객체인 khw는 __proto__를 통해 자신의 부모였던 Person.prototype부분에 접근을 할 수 있다.

  • Person.prototype.constructorkhw.__proto__.constructor는 같은 Person 생성자함수를 나타낸다.


4. 클래스

class Person {
  constructor(name, address) {
    this.name = name;
    this.address = address;
  }

  getInformation() {
    console.log(`${this.name} ${this.address}`);
  }
}

const khw = new Person("khw", "seoul");
const msk = new Person("msk", "busan");
const heesu = new Person("heesu", "pohang");

console.log(khw);	//Person {name: "khw", address: "seoul"}
console.log(msk);	//Person {name: "msk", address: "busan"}
console.log(heesu);	//Person {name: "heesu", address: "pohang"}

console.log(khw.__proto__);		//{getInformation: ƒ, constructor: ƒ}
console.log(msk.__proto__);		//{getInformation: ƒ, constructor: ƒ}
console.log(heesu.__proto__);		//{getInformation: ƒ, constructor: ƒ}

3번과 마찬가지로 같은 결과이다.


왜? 클래스는 prototype을 사용해서 함수를 설정하지 않는가?

  • 클래스는 프로토타입을 사용하여 만든것이기에 저절로 prototype으로 처리한다.

(내가 알기론 늦게 JS에 class 개념이 나왔는데 생성자함수 쓸 때보다 이점이 있어야지 이런식으로 )


심화 => 프로토타입 체인

간단히 체인을 연결하여 부모까지 가서 계속 값이 존재하는지 확인하고 결과를 처리하는 것이다.

function Ultra(){}  //생성자
Ultra.prototype.ultraProp = true;
 
function Super(){}
Super.prototype = new Ultra();
 
function Sub(){}
Sub.prototype = new Super();
 
var o = new Sub();
console.log(o.ultraProp);		//true

객체 o는 자신이 가지고있지않는 ultraProp를 찾기 위해 부모로 계속해서 찾아올라가 Sub -> Super -> Ultra -> Ultra.prototype의 값을 발견하고 true를 출력한다.

그림으로는 이와같다. (사실 설명하기 어렵긴하다.)


내용설명

  1. 최상위는 Object객체가 있다.
  2. Object를 가리키는 f()라는 함수가 있다.
  3. f()을 __proto__를 통해 가르키는 각각의 함수들이 있다.
  4. sub의 객체인 o는 prototype을 통해 파란색 화살표 방향으로
    ultra.prototype까지 프로토타입체인을 연결하며 Ultra.prototype.ultraProp 값에 도달한다.

정리

생성자함수에서는 일일히 prototype을 함수에 붙여 메모리 낭비를 해결했으나 prototype개념인 class를 통해 따로 prototype을 붙이지 않고도 이를 해결했다.

prototype vs __proto__ vs constructor의 서로간의 차이를 이해해야한다.

  • 오류가 있을시 댓글로 남겨주시면 감사하겠습니다
profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글