JavaScript

[JavaScript/ES6] prototype(프로토타입) - 상속 기능 구현 / prototype 특징

김나나_ 2024. 8. 27. 14:02

자바스크립트에서는 cunstructor 말고도 상속기능을 구현할 수 있는 장치가 하나 더 있다.

바로 prototype(프로토타입) 이다.

 

다음과 같이 MakeProd 라는 상속자함수가 있다고 하자.

function MakeProd (name, price) {
    this.name = name;
    this.price = price;
    this.부가세 = function() {
        console.log('부가세는 ' + this.price * 0.1 + '원 입니다.');
    }
}

var prod1 = new MakeProd('shirt', 50000);
var prod2 = new MakeProd('pants', 60000);

 

makeProd 안에넌 prototype 이라는 항목을 내부에 몰래 생성한다.

 

prototype

= 부모의 유전자역할을 해주는 일종의 비밀 공간

= 자식들이 물려받을 수 있는 유전자

 

MakeProd.prototype 은 MakeProd 의 유전자이다.

MakeProd.prototype 에 변수나 함수가 들어가 있다면 MakeProd 로 부터 생성되는 새로운 오브젝트들(자식들)은 전부 그걸 그대로 물려받아 쓸 수 있다.

 

function MakeProd (name, price) {
    this.name = name;
    this.price = price;
    this.부가세 = function() {
        console.log('부가세는 ' + this.price * 0.1 + '원 입니다.');
    }
}

MakeProd.prototype.quantity = 100; // 프로토타입
var prod1 = new MakeProd('shirt', 50000);
var prod2 = new MakeProd('pants', 60000);

 

- prototype 에는 값을 여러 개 부여할 수 있고, 함수도 넣을 수 있다. (object 자료형 처럼 다루면 됨)

- prototype 에 추가된 데이터들은 자식들이 직접 가지는 게 아니라 부모만 가지고 있다.

 

📌 prototype 의 작동 원리

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}

기계.prototype.gender = '남';
var 학생1 = new 기계();

console.log(학생1.gender) // '남' 출력됨

 

자바스크립트는 오브젝트에서 값을 출력할 때 이런 순서로 물어본다.

1) 학생1 에 직접 gender 라는 값이 있는가?

2) 그럼 부모 유전자에 gender 라는 값이 있는가?

3) 그럼 부모의 부모 유전자에 gender 라는 값이 있는가?

4) 그럼 부모의 부모의 부모 유전자에 gender 라는 값이 있는가?

....

 

 

즉, 오브젝트에서 값을 뽑을 때

1. 내가 직접 가지고 있는 지 검사

2. 내가 가지고 있지 않으면 부모 유전자들을 차례로 검사

 

이런 로직으로 동작한다!

 

💙 자바스크립트 내장함수 toString() 을 쓸 수 있는 이유?

자바스크립트에넌 array, object 들에는 붙일 수 있는 내장함수들이 많다

sort, push, toString, map, forEach 등 array 에 붙여서 사용가능하다.

 

내가 만든 array 에 array.toString() 이렇게 붙일 수 있는 이유는

내가 만든 array의 부모 유전자가 toString() 을 가지고 있기 때문이다. (부모 또는 부모의 부모)

 

우리가

var arr = [1,2,3]; 

으로 array 선언한 것은 사실

var arr = new Array(1,2,3); 과 같다.

 

Array 라는 생성자 함수로부터 생성한 것이라는 뜻이다!

var arr = [1,2,3];  

라고만 해도 내부적으로는 new 키워드를 항상 이용해서 array, object 를 생성한다.

 

따라서, Array로부터 생성된 자식들은 Array 유전자에 부여되어 있는 함수, 데이터들을 자유롭게 사용가능하다.

 

 

Array.prototype 을 콘솔로그로 찍어보면 sort, map 등을 찾아볼 수 있다.

(Object 자료형도 마찬가지)

 

 

 

💙 prototype 으로 상속시키는 것과 constructor 로 상속시키는 것의 차이점은 ?

자식들이 값을 직접 소유하게 만들고 싶으면 constructor 로 상속 시키고

부모만 가지고 있고 그걸 참조해서 쓰게 만들고 싶으면 prototype 으로 상속시키면 된다.

보통은 상속할 수 잇는 함수 같은 것들은 prototype 으로 많이 만든다.

 

this.sayHi 보다 prototype 에 기계.prototype.sayHi 로 메소드를 지정하는 것이 더 효율적이다.
prototype은 모든 객체가 공유하고 있어서 한 번만 만들어지지만, this 에 넣은 것은 객체 하나를 만들때마다 메소드도 하나씩 만들어지기 때문에 불필요한 메모리 낭비가 발생한다.
(아예 메소드뿐만 아니라 속성까지도 다 prototype 에 넣기도 한다)

 

 

 

참고 :

코딩애플 강의

https://www.zerocho.com/category/JavaScript/post/573c2acf91575c17008ad2fc

 

(JavaScript) 객체 지향 프로그래밍(생성자와 프로토타입)

이번 시간에는 자바스크립트식 객체 지향 프로그래밍(OOP, Object Oriented Programming)에 대해 알아보겠습니다. 생성자 지난 시간에 Date 객체를 new Date()로 만들었던 것 기억하시나요? Date는 분명 객체라

www.zerocho.com

 

📌 prototype 특징

1. prototype 은 constructor 함수에만 몰래 생성된다.

var arr = [1,2,3]; 

처럼 일반 array 에는 prototype 이 없다.

 

var arr = new Obeject();

에서 Object 에는 prototype 이 있다.

 

🔎 일반 object 에도 상속기능을 만들고 싶다면?

1. constructor 함수를 만들기

2. Object.create() 활용

3. Class 활용

 

셋 중 하나를 활용하면 된다.

 

2. 내 부모님 유전자를 찾고 싶다면 __prototype__ 출력해보기

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}
var 학생1 = new 기계();
console.log(학생1.__proto__);
console.log(기계.prototype);

 

동일한 값이 출력됨을 알 수 있다.

 

__proto__부모 prototype 을 의미한다.

__proto__ 는 내 부모 유전자가 뭔지 검사하고 싶을 때 활용하면 된다.

 

3. __proto__ 를 직접 등록하면 object 끼리 상속기능 구현 가능

어떤 object 에다가 __proto__ 를 강제로 하나 설정하면 강제로 부모님을 만들어줄 수(?) 있다.

 

자식에 강제로 __proto__ 를 이용하여 부모를 상속시켰다.

자식의 부모 유전자는 { name : 'Kim' } 이라는 오브젝트가 된다.

 

자식.name 이 Kim 으로 출력됨을 확인 할 수 있다.

 

4. 콘솔창으로 prototype 정보 출력 가능

 

 

기계의 prototype 을 살펴보면

부모가 Object 인 것을 확인할 수 있다.

 

이런식으로 콘솔창을 확인하여 부모, 부모의 부모,, 등등 탐색할 수 있다.

 

 

탐색을하다보면 모든 object 의 자료형의 조상은 Object() 라는 기계이다. (= Object.prototype)

모든 array 자료형의 조상도 Object() 이다. (중간에 Array() 라는 부모가 있음)

모든 함수 자료형의 조상도 Object() 이다.

=> 자바스크립트는 모든게 다 Object 라고 불리는 이유이다!