※ 이 글은 예전 블로그에서 퍼온 글입니다. 가독성이 나쁘다면 예전 블로그 에서 읽어주세요.
※ 글 중 모르는 단어나 개념이 있으실까봐 맨 아래에 참고할만한 사이트들을 남겨둡니다.
1. 객체지향 프로그래밍(Object-Oriented-Programming)
객체지향 프로그래밍은 현실 세계에 존재하는 객체(Object)를 소프트웨어 세계에서 표현하기 위해 객체의 핵심적인 부분만을 추상화해 모델링 하려고 하는 프로그래밍 패러다임을 말합니다.
이해가 잘 안되신다면 객체를 사물이나 과일로 바꿔 이해하면 쉽습니다.
붕어빵을 예로 들자면, 팥 붕어빵이라는 객체를 소프트웨어 세계에서 구현하기 위해 팥 붕어빵의 핵심적인 특징(붕어 모양, 팥)을 생각해 모델링 하고자 하는 것입니다.
각 객체들을 독립적인 기능을 지닙니다.
하지만 객체들은 서로 협력하여서 문제를 해결하거나 다양한 기능을 수행할 수 있습니다.
객체지향 프로그래밍은 이러한 객체들을 이용해 코드를 유지 보수(Refactoring) 하기 쉽게 해주며 확장성 측면에서도 뛰어납니다.
2. 클래스(Class)와 프로토타입(Prototype)에 대하여
자바스크립트는 멀티 패러다임 언어로 명령형(Declarative), 함수형(functional), 프로토타입(prototype) 기반의 객체지향 언어입니다.
(정확히 말하자면 객체기반 언어라고 하기도 하지만 일단 객체지향이라 말 하겠습니다.)
하지만 다른 언어와는 달리 Class를 지니고 있지 않습니다.
(ES6에서는 Class 문법이 추가되었습니다. 하지만 이것은 문법이 추가된 것이지 절대 자바스크립트가 Class기반의 언어가 된 것은 아닙니다.)
2-1. 클래스(Class)
그럼 먼저 객체지향에서 중요하게 여기는 Class란 무엇일까요?
Class는 같은 종류의 집단에 속하는 속성(attribute)과 행위(behavior)를 정의한 것으로 기본적인
사용자 정의 데이터형(user define data type)이라고 할 수 있습니다.
그래서 Class는 객체지향 프로그래밍에서 객체를 만들기 위한 청사진(blueprint)과 같은 역할을 하며,
객체를 만들기 위해선 new 연산자를 이용해 인스턴스화할 필요가 있습니다.
아까처럼 붕어빵을 예시로 들자면, 우리는 팥 붕어빵이란 객체를 만들고 싶습니다.
그러기 위해서 붕어빵의 핵심적인 특징을 생각해봅시다.
붕어 모양, 내용물, 반죽 등등 여러 가지가 있을 것입니다.
(이러한 것들이 Class가 가지는 속성과 행위에 해당하는 것들입니다.)
우리는 이러한 정보를 토대로 팥 붕어빵을 만들 것입니다.
그래서 내용물은 팥을 넣고 반죽은 밀가루 반죽을 이용하여 우리는 팥 붕어빵이란 객체를 만들었습니다.
(녹차 붕어빵을 만들고 싶다면 녹차가루, 녹차반죽을 넣으면 됩니다. 이것이 바로 확장성이 뛰어난 이유입니다.)
다시 자바스크립트 얘기를 하자면 자바스크립트는 이러한 Class가 없습니다. 하지만 자바스크립트가 객체지향 언어라고 불리는 이유는 Prototype을 기반으로 한 다음과 같은 객체 생성법이 존재하기 때문입니다.
1. 객체 리터럴
var human = {}; human.age = "20";
2. Object( ) 생성자 함수 (Constructor function)
var human = new Object(); human.age = "20";
3. 사용자 정의 생성자 함수
// 생성자 함수의 이름은 일반적으로 대문자로 시작합니다. // this는 생성자 함수가 생성할 인스턴스(instance)를 가리킵니다. function Human(age) { this.age = age } var grandfa = new Human(80);
그럼 객체를 생성하는 방법은 알겠는데 Prototype이란 무엇일까요?
2-2. 프로토타입(Prototype)
(저는 클래스, 프로토타입 객체와 링크, 프로토타입 프로퍼티, 생성자 함수, __proto__, constructor에 깊은 빡침을 느꼈습니다..)
Prototype은 자바스크립트에서 매우 중요하지만 많은 사람들에게 혼란을 줄 수 있습니다.
그렇기 때문에 조심해야하며 개념을 확실히 해야 합니다..!
Prototype은 단어적으로 기초, 표준, 원형, 초기모델 이라는 의미를 가집니다.
타 언어에서의 Class와 자바스크립트의 Prototype은 의미적으로는 비슷합니다.
Class에서 팥 붕어빵 객체를 만들기 위한 붕어빵 Class라고 이해하시면 됩니다.
하지만 절대 Class와 Prototype을 동일시 하면 안됩니다.
왜냐하면, Class는 상속이 가능하지만 Prototype은 상속이 불가능하기 때문입니다.
그럼 Prototype은 어떻게 상속하여 객체지향을 구현할 수 있는가?
→ 프로토타입 체인(Prototype Chain)을 형성하여 상속합니다.
자바스크립트의 Prototype은 보통 Prototype Object와 Prototype Link를 통틀어 얘기합니다.
이에 대해 설명하기 전, 다시 객체를 만들기 위한 생성자 함수(Constructor function)로 돌아가봅시다.
아까전 저는 Prototype 기반으로 객체를 만드는 방법이 3가지를 소개했습니다.
하지만, 객체 리터럴 방식은 함수랑 전여 상관없어 보이는 코드인데 어떻게 객체를 만들 수 있을까요?
var human = {}; 과 var human = new Object(); 는 같은 표현입니다.
그 이유는 객체 리터럴 방식으로 생성된 객체는 결국 내장 생성자 함수인 Object 생성자 함수로 객체를 생성하는 것을 단순화시킨 축약 표현(short-hand)이기 때문입니다.
전하고 싶은 바는 다음과 같습니다.
1. 객체는 함수를 통해 만들어 진다.
2. Array, Function, Object, String과 같은 내장 생성자 함수들은 모두 함수로 정의되어 있다.
(왜냐? 함수가 아니면 객체를 생성하지 못하기 때문에 생성자 함수라고 할 수 없기 때문입니다.)
2-3. 프로토타입 객체 (Prototype Object)
그럼 위에서 말한 것을 명확히 하고 Prototype Object에 대해 살펴 봅시다.
우리가 자바스크립트로 함수를 생성할 때, 자바스크립트 엔진은 함수에 Prototype 프로퍼티를 추가합니다.
이 Prototype 프로퍼티는 constructor 프로퍼티를 고정으로 가지는 객체(Object)입니다.
그럼으로 Prototype 프로퍼티와 Protopype Object는 같습니다. (충격)
constructor 프로퍼티는 Prototype Object를 프로퍼티로 가지는 함수를 가리킵니다.
그래서 우리는 함수의 Prototype 프로퍼티를 사용하여 Prototype Object에 접근할 수 있습니다.
요약하자면, 함수를 만들면 함수는 Prototype Object를 Prototype 프로퍼티로 가진단 소립니다.
+ 추가설명
1. foo라는 생성자 함수를 생성하면 Prototype이라는 프로퍼티를 가집니다.
2. 리터럴 객체로 생성한 obj 객체는 Prototype 프로퍼티가 없기 때문에 new 연산자를 사용하여 인스턴스를 생성하지 못합니다.
3. 1번과 비교해보면 foo 함수가 가지는 Prototype 프로퍼티와 Prototype Object는 같음을 알 수 있습니다.
4. Prototype Object의 constructor 프로퍼티를 이용해 foo 함수에 접근할 수 있습니다.
5. foo 함수와 Prototype Object의 관계
+ 참고하면 좋은 글들
'Programming > Javascript' 카테고리의 다른 글
Babel의 뜻과 사용법 (0) | 2020.04.07 |
---|---|
Doom이 아니라 DOM! (문서 객체 모델, Document Object Model) (0) | 2020.04.02 |
BOM (Browser Object Model)에 대한 정리 (0) | 2020.04.02 |
생성자의 문제점 (생성자 함수를 쓸 때 주의 할 점) (0) | 2020.04.02 |
Drag and Drop과 관련하여 (Mozilla 참고) (0) | 2020.04.02 |