Javascript - prototype이란?

2021. 5. 31. 18:41프론트엔드/React.js

728x90

TypeScript 핸드북을 보다가 prototype에 대한 부분이 나왔다.
사실 javascript에 대한 것에 대해 검색하다보면 이런게 나온다.

const a = new A();
a.prototype.name = "~~~";

 

사실 자바스크립트를 오랫동안 썼지만, Unity에서 쓰다가 React로 바로 넘어오다보니,
클래스 위주의 방식만 사용을 했다. 그래서 prototype이 그냥 옛날에 사용하는 그 뭐시긴가 보다 생각했다.
이번 기회에 공부하는김에 탐구해보기로 하였다.


모든 객체는 Prototype을 가진다.

여기서 객체란 함수, Object등 원시 타입(primitives)가 아닌 모든 것을 말한다.
즉, 함수에도 멤버를 붙일수가 있다.

function getMax(a, b) {
	return a;
}

getMax.abc = "히히";

이게 된다고? 왜?

클래스만 쓰던 유교보이은 이 자유분방함에 머리가 띵해져버렸다.

클래스 유교보이의 입장에서 정리를 해보겠다.
1. 모든 원시 타입이 아닌 것은 객체다.
2. 객체는 멤버를 가진다.
3. 함수는 그저 인자를 받으면 작동하는 멤버중 하나일 뿐이다.
4. 근데 함수도 객체가 될수있다 ^_______^

왜 자바스크립트를 싫어하는 사람들이 있는지 알겠다.

그런데 이제 이런 객체가 만들어지기에 앞서서 prototype이 만들어진다.
클래스로 예를 들자면 "일단 객체를 만들었더니 클래스가 생겼다"?


Prototype은 하위 객체들의 원형이 된다.

여기서부터 중요한데, 모든 객체는 자신만의 별도의 property를 가질 수 있다.
그리고 객체의 원형인 prototype도 원할 때 property를 추가할 수 있다.

function inho() {}

const a = new inho();
a.age = 27;
// 객체 a만의 property가 생성됨
// 출력: 27
console.log(a.age);

// inho의 prototype에 property 추가
inho.prototype.type = "원숭이";

// 출력: { type: '원숭이' }
console.log(inho.prototype);

// a를 출력한다고 해서 prototype의 정보까지 출력되지는 않는다
// 출력: inho { age: 27 }
console.log(a);

// a.type을 호출하면 원형인 prototype.type이 불러진다.
// 출력: 원숭이
console.log(a.type);

// 같은 이름으로 덮어씌우면 덮어씌운 값으로 출력된다.
// 출력: 오랑우탄
a.type = "오랑우탄";
console.log(a.type);

// 객체의 값을 바꾼다고 해서 원형은 바뀌지 않는다.
// 출력: { type: '원숭이' }
console.log(inho.prototype);

// 원형이 바뀌지 않았으므로, 새 객체를 만들어도 원형의 값으로 나온다.
const b = new inho();
// 출력: 원숭이
console.log(b.type)

이 난국 속에서 상속까지 가능하다고?

이 프로토타입형 언어는 대체 상속을 어떻게 할까?
천천히 알아보자. 나도 잘 모르겠어서 천천히 갑시다

이 부분에 대해서 아래 출처에 나온 사이트에서 잘 정리해주셨다 (감사합니다)
여러가지에 대해 정리해주시며 발전해나갔는데, 프로토타입공유에 대해 정리해보겠다.

function Person(name) { this.name = name || "인호"; }

Person.prototype.getName = function() { return this.name; }

// 자식의 프로토타입을 부모의 프로토타입으로 지정함.
Korean.prototype = Person.prototype;

const kor1 = new Korean("아름");
// 출력: 아름
console.log(kor1.getName());

다음과 같이 자식의 프로토타입을 부모의 프로토타입으로 지정하면서 부모의 property를 가져오는 것이다.

그러면 여기서 이런 의문이 들 수 있다.
"자식의 prototype에 property를 추가하면 부모에도 추가가 되나?"
직접 해보자.

function Person(name) { this.name = name || "인호"; }

Person.prototype.getName = function() { return this.name; }

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

Korean.prototype = Person.prototype;

// 자식에 property 추가
Korean.prototype.age = 27;

const per1 = new Person("진호");
// 출력: 27, 진호
console.log(per1.age, per1.getName());

const kor1 = new Korean("아름");
// 출력: 27, 아름
console.log(kor1.age, kor1.getName());

아... 분명 자식의 prototype에 property를 추가했지만 부모에게도 추가되었다.
사실 사진에서도 알 수 있지만 부모의 생성자를 사용하지 않고도 사용하는 방법이다.

결론: 그만 알아보자.


출처

https://www.nextree.co.kr/p7323/

 

JavaScript : 프로토타입(prototype) 이해

JavaScript는 클래스라는 개념이 없습니다. 그래서 기존의 객체를 복사하여(cloning) 새로운 객체를 생성하는 프로토타입 기반의 언어입니다. 프로토타입 기반 언어는 객체 원형인 프로토타입을 이

www.nextree.co.kr