티스토리 뷰
자바스크립트의 객체지향적 특성에 대해 공부하며 프로토타입 기반의 언어라는 내용이 계속 나왔지만
한번에 다 이해할 수가 없어서.. 때되면 이해할 수 있겠지 하며 넘겨왔었다.
그리고 이제 드디어 정리가 좀 되는 중!
👀 Prototype 이란?
프로토타입은 유전자 같은 것이다. 부모가 가진 유전자를 기반으로 자식객체를 만드는 개념이다.
자바스크립트가 프로토타입 기반 언어라는 것은 결국 객체지향적 특성을 설명한다.
클래스 기반 객체지향 VS 프로토타입 기반 객체지향
객체지향은 블럭을 조립해 제품을 만들어가는 과정 같은 것이라고 했다.
Java 나 Python, C++ 같은 언어에서는 클래스를 정의해 그것으로부터 블럭(자식 객체)을 만들어 나간다면,
Javascript는 클래스 없이 부모의 유전자를 가진 자식객체를 만들어낸다.
(사실은 프로토타입을 기반으로 클래스 상속을 흉내내는 것이라 한다.
ES6에서는 Class 문법이 추가되었지만 자바스크립트가 클래스 기반으로 바뀐 것은 아니다.)
👀 앞서 Constructor 만들기를 배우면서 이미 상속기능을 배웠다.
function Person() {
this.name = 'Jessie';
this.age = 20;
}
var person1 = new Person(); // output : {name: 'Jessie', age: 20}
constructor를 사용해서 오브젝트를 만들었을때, 만들어진 자식 객체는 부모 constructor와 같은 유전자를 같게된다.
그런데 위와 같이 constructor를 통해 만든 자식객체의 수가 많아진다면, 각 변수에 할당되는 메모리가 그만큼 많아진다.
그래서 자식객체가 언젠가 가져다 쓸 수 있는 유전정보로서 값을 저장할 수 있도록 prototype 키워드를 사용한다.
constructor를 통해 만들어지는 모든 자식객체는 prototype에 할당된 값을 가져다 쓸 수 있다.
function Person() {}
Person.prototype.name = 'Jessie';
Person.prototype.age = 20;
var person1 = new Person(); // output : Person{}
console.log(person1.name); // output : Jessie
위 코드처럼, Person을 통해 만들어진 자식 person1은 비어있지만,
prototype을 통해 할당된 name의 값을 가져다 쓸 수는 있다.
👀 왜 가져다 쓸 수 있게 되는걸까?
1. 결국 다 constructor 함수로부터 생성된 것이다.
우리는 객체를 만들때 var obj = { key : value }의 형태로 선언하지만
사실 컴퓨터는 위 코드를 var obj = new Object() 의 형태로 실행한다.
Object라는 constructor를 통해 인스턴스(자식객체)를 만들어내는 것이다.
객체와 마찬가지로, 배열이나 함수도 Array(), Function()과 같은 constructor로부터 만들어진다.
(그런데 Array(), Function()의 조상도 결국은 다 Object()이다. 자바스크립트의 모든 것은 결국 객체이다.)
var data = {};
console.log(data.__proto__ == Object.prototype) // true
위 코드에서 함수와 관계없어 보이는 data 오브젝트를 생성했지만,
사실은 자바스크립트가 기본으로 제공하는 함수인 Object라는 constructor를 통해 만들어진 자식객체이기 때문에,
자식의 유전자를 확인하는 data.__proto__와 부모가 가진 유전자를 확인하는 Object.prototype의 비교가 true로 나올 수 있는 것이다.
(Object.getPrototypeOf(자식객체이름) 로도 자식객체의 유전자를 확인할 수 있다)
결국 모든 자료의 최종 부모는 다 constructor 형태로 존재한다.
그리고 그 최종 부모에게는 내장함수들이 기본적으로 들어있다.
그래서 내가 직접 선언한적이 없는 sort, push, toString, forEach 등의 내장함수를 사용할 수 있는 것이다.
2. 자바스크립트는 항상 부모의 유전자를 확인해서 값을 가져온다. (Prototype chain)
모든 객체는 부모의 유전자 정보가 들어있는 [[Prototype]] 슬롯을 갖지고 있다.
그리고 자바스크립트에서 오브젝트의 값을 가져올때는
1. 해당 오브젝트가 그 값을 가지고 있는가? 있으면 리턴
2. 없으면, 부모가 그 값을 가지고 있는가? 있으면 리턴
3. 없으면, 부모의 부모가 그 값을 가지고 있는가???
하는 방식으로 작동한다.
(찾을 수 있는 부모를 다 찾아봤는데도 값이 없다면, undefined를 리턴한다.)
👀 prototype 활용하기
1. __proto__로 오브젝트끼리 상속기능 구현하기
var person = {name: 'Jessie'};
var student = {};
student.__proto__ = person;
console.log(student.name); // output : Jessie
student 오브젝트는 비어있지만, __proto__를 통해 부모 유전자를 만들어줌으로서 person의 name 속성을 이용할 수 있게 되었다.
2. ES5 문법인 Object.create() 활용하기
var person = {name: 'Jessie'}
var student = Object.create(person);
console.log(student.name); // output : Jessie
1번과 마찬가지로 student 오브젝트는 비어있지만 Object.create()를 통해 person을 부모 유전자로 만들어줄 수 있다.
3. ES6 문법인 Class 활용하기
는 추가 포스팅으로 정리하는게 좋겠다.
참고
https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
https://poiemaweb.com/js-prototype
'Javascript' 카테고리의 다른 글
[JS] 원하는 DOM node 잡아오기 (0) | 2022.04.03 |
---|---|
[JS] 자바스크립트의 Class 문법 (0) | 2022.02.13 |
[JS] Reference data type 개념 정리 (0) | 2022.01.29 |
[JS] Spread operator (스프레드 연산자) 활용하기 (0) | 2022.01.13 |
[JS] Template literals & Tagged templates (0) | 2022.01.12 |
- Total
- Today
- Yesterday
- CSS
- notworking
- Prototype
- JQuery
- 생각정리
- 조건부삼항연산자
- 다중조건삼항연산자
- scrollEvent
- JSX
- 구조분해할당
- ES6
- 삼항조건연산자중복사용
- JS
- Prettier
- Til
- destructuring
- typescript
- Asynchronous
- 리액트
- javascript
- promise
- VSCode
- callsignature
- 타입스크립트
- Callback
- DOM
- Ternary
- class
- 개념정리
- Synchronous
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |