* 프로토타입(Prototype)이란?
- 원형이라는 뜻
- 완성된 형태가 아닌 빠르게 스캐치한것, 실제 제품을 만들기전 대략적인 형태를 만들어낸것
- 또는 집합체안에 비슷한 특징들을 뽑아서 대략적인것을 나타내도록 만든것
- 배포전 단계에서 빠르게 만들어낸 어플리케이션을 프로토타입 어플리케이션이라고 말한다.
- 자바스크립트에서 프로토타입은 다양한 객체들간에 비슷한 특징을 클래스로 만든것처럼
- 즉, 생성자함수를 통해서 템플릿으로 만든것처럼 객체지향프로그래밍을 위해서 바로 이 프로토타입을 사용한다.
- 다양한 오브젝트들이 있다면 이들의 비슷한 점들을 하나의 프로토타입으로 만들어서 이 프로토타입을 이용해서
객체지향을 구현한다.
* 자바스크립트란 프로토타입을 베이스로 한 객체지향 프로그래밍 언어이다.
- 객체지향 프로그래밍을 위해서 대부분 Class를 사용하는데 자바스크립트에서는 Prototype을 사용한다.
- 최신 문법에는 Class사용도 추가되었다.
- 자바스크립트는 Prototype를 사용하고 최신 문법에는 Class가 추가되었다.
- TS, Java는 Class를 사용한다.
- 요즘 웹어플리케이션이나 Node나 백엔드 같은 경우에서 TS를 많이 쓴다. 그래서 객체지향을 구현하기 위해 Class를 많이 이용한다.
- JS에서도 많은 기능은 없지만 Class를 구현할 수 있어서 Class를 이용한다.
* 자바스크립트에서 모든 객체는 Object라는 Prototype를 가지고 있다.
- 왜냐?? 객체간 상속을 위해 자바스크립트에서 객체라면 공통적으로 가지고 있는 속성들 함수들을 묶어놓은 원형인 Object라는 이름을 가진 Prototype를 가지고 있다.
- Prototype는 외부에서 직접 접근 불가
- __proto__
- Object.getPrototypeOf()
- Object.setPrototypeOf()
- 생성자 함수에서는 : prototype으로 접근 가능
사실 모든 자바스크립트 객체들은 개별적인 Object Prototype을 상속하는게 아닌 동일한 Object Prototype(단 하나의 Object Prototype)을 상속한다.
const array = [];
array라는 빈 배열을 만들어주면 Array라는 Prototype를 가지고 있는것을 알 수 있다.
텅텅빈 배열이지만 아무런 함수도 정의하지 않았지만 배열에서 제공해주는 기본적인 함수를 사용할 수 있는 이유는
바로 Array라는 Prototype가지고 있어서 배열의 함수들을 사용할 수 있다.
그리고 Array Prototype는 결국 Object Prototype를 상속하고 있어서 객체에서 사용할 수 있는 모든함수들을 사용할 수 있다.
자바스크립트에서 객체간 상속의 연결 고리는 프로토타입 체인으로 연결 되어 있음
* 인스턴스 레벨의 함수
- 만들어진 인스턴스마다 모두 해당 함수를 가지고 있다.
- 따라서 메모리 낭비가 발생한다.
* 프로토타입 레벨의 함수
- 만들어진 인스턴스에는 들어있지 않고 prototype에 들어있다.
- 조금 더 메모리를 절약할 수 있다.
* 오버라이딩
- 인스턴스 레벨에서(자식) 동일한 이름으로 함수를 재정의 하면 (오버라이딩 하면)
- 프로토타입 레벨의(부모) 함수의 프로퍼티는 가려진다 (shadowing된다.)
- 자식 레벨에서 함수를 재정의하지 않으면 prototype에 있는걸 쓴다.
* 정적 레벨
- Class의 static function과 동일한 느낌
- Class의 이름에서 접근이 가능한 함수
- 생성자이름.함수 = () =>
// const dog1 = { name: '뭉치', emoji: '🐶' };
// const dog2 = { name: '코코', emoji: '🐩' };
function Dog(name, emoji) {
this.name = name;
this.emoji = emoji;
// 1.인스턴스 레벨의 함수
// 만들어진 인스턴스마다 모두 해당 함수를 가지고 있다.
// 메모리 낭비가 발생한다.
/* this.printName = () => {
console.log(`${this.name} ${this.emoji}`);
}; */
}
// 2.프로토타입 레벨의 함수
// 만들어진 인스턴스에는 들어있지않고 prototype에 들어있다.
// 조금 더 메모리를 절약할 수 있다.
Dog.prototype.printName = function () {
console.log(`${this.name} ${this.emoji}`);
};
// 생성자 함수를 통해 새로운 객체를 생성
const dog1 = new Dog('뭉치', '비글');
const dog2 = new Dog('코코', '푸들');
console.log(dog1, dog2);
// prototype에 printName함수가 포함되어 있기 때문에 사용이 가능하다.
// 만들어진 dog1, dog2는 Dog라는 prototype를 가지고 있기 때문이다.
dog1.printName();
dog2.printName();
// 오버라이딩
// 인스턴스 레벨에서(자식) 동일한 이름으로 함수를 재정의 하면 (오버라이딩 하면)
// 프로토타입 레벨의(부모) 함수의 프로퍼티는 가려진다 (섀도잉 됨)
// 자식 레벨에서 함수를 재정의하지 않으면 prototype에 있는걸 쓴다.
dog1.printName = function () {
console.log('안녕!!');
};
dog1.printName();
// 3.정적 레벨
// Class의 static function과 동일한 느낌
// Class의 이름에서 접근이 가능한 함수
// 생성자이름.함수 = () =>
Dog.hello = () => {
console.log('Hello!');
};
Dog.hello();
// 공통된 속성이 있다면 지정이 가능하다.
// 생성자이름으로 통해 접근이 가능하다.
// console.log(Dog.MAX_AGE)
Dog.MAX_AGE = 20;
'Study > JavaScript' 카테고리의 다른 글
[JavaScript_study] freeze (불변성을 추구할 때) (0) | 2022.04.14 |
---|---|
[JavaScript_study] 프로퍼티(property) (0) | 2022.04.14 |
[JavaScript_study] 엄격 모드 (strict mode) (0) | 2022.04.14 |
[JavaScript_study] var을 쓰지 말자 (0) | 2022.04.14 |
[JavaScript_study] 호이스팅 (Hoisting) (0) | 2022.04.14 |