What is OOP?
- OOP(Object-Oriented Programming, 객체 지향 프로그래밍)란 객체 개념에 기반을 둔 프로그래밍 패러다임을 의미한다.
- 객체를 이용하면 property에 해당하는 데이터와 method에 해당하는 동작을 하나의 큰 블록(객체)에 담을 수 있다.
- 데이터와 동작이 담긴 객체는 독립적인 작은 앱처럼 동작하며 그 객체들끼리 상호작용한다.
- OOP는 더 유연하고 유지 보수하기 쉽도록 코드 조직화를 하기 위해 개발된 프로그래밍 패러다임이며 대규모 소프트웨어 엔지니어링 분야에서 광범위하게 사용되고 있다.
- 전통적인 OOP는 클래스를 사용하지만 자바스크립트는 클래스가 아닌 프로토타입을 사용한다.
Class and Instance
OOP에서는 객체 리터럴뿐만 아니라 객체를 프로그래밍적으로 생성할 방법이 필요하다.
전통적인 OOP에서는 클래스라는 것을 이용한다. (클래스 기반 OOP)
Class
- 클래스는 보통 청사진(blue print)으로 묘사된다.
- 클래스는 단순 설계도이기 때문에 실체가 없다.(데이터와 데이터관련 동작이 있지만 데이터 자체는 아니다.)
- 클래스에 묘사된 청사진에 따라 새로운 객체를 만들 수 있다.
- JavaScript에는 실제 클래스를 지원하지 않는다.(클래스 문법이 있지만 전통적인 클래스와는 다르게 동작한다.)
Instance
- 인스턴스는 클래스라는 청사진을 보고 만든 실제 객체를 의미한다.
- 클래스를 통해 필요한만큼 많은 객체를 생성할 수 있다.(이 과정을 Instanciation이라 한다.)
- 같은 클래스(설계도)를 보고 만든 것이기 때문에 모두 같은 기능을 가지고 있으면서, 서로 다른 데이터를 가질 수 있다.
The 4 Fundatmental OOP Principles
좋은 클래스는 어떻게 디자인되어야 할까.
4가지 고려 사항이 있다.
Abstraction(추상화)
- 추상화란 사용자에게 필요한 정보만 제공하고 부가적인 것은 최소화하는 것을 의미한다.
프로그래밍을 할 때도 우리는 프로그래밍 언어의 사용자이기 때문에 언어를 완전히 이해하거나 직접 구현하지 않아도 추상화를 통해 언어가 제공하는 기능을 간단히 사용할 수 있다.
Encapsulation(캡슐화)
- 일부 property와 method를 외부에서 접근하지 못하도록 막는 것을 의미한다.
- 외부 코드가 내부의 데이터를 직접 조작할 수 있을 경우 많은 종류의 버그가 발생할 수 있다. 그래서 항상 객체 내의 일부 property와 method를 캡슐화하고 핵심적인 method만 공개한다.
- 공개된 method는 public API라고도 부른다.
Inheritance(상속)
- 유사한 두 클래스가 있을 때, 중복된 코드를 작성하지 않고 하나의 클래스가 다른 클래스를 상속할 수 있게 한다.
- parent class와 child class가 있고, child class가 부모로부터 상속받게 될 경우 parent class의 모든 property와 method를 물려받는다.
- 상속을 통해 두 클래스 사이에 계층구조가 형성되고, 공통 로직을 재사용할 수 있다.
Polymorphism(다형성)
- 그리스어에서 유래, '다수의 형태'라는 뜻이다.
- 간단히 말해서 parent class에서 물려받은 method를 바꿔야 하는 경우 원하는대로 커스텀할 수 있다.
OOP in JavaScript
OOP가 Javascript에서 동작하는 원리
자바스크립트에서 OOP는 전통적인 클래스가 아닌 프로토타입을 이용한다.
Prototypal Inheritance(프로토타입 상속) 이용.
- 자바스크립트의 모든 객체는 특정 프로토타입 객체에 연결되어 있다.(즉 모든 객체는 프로토타입이 있다.)
- 프로토타입 객체는 프로토타입에 연결된 모든 객체가 접근하고 사용할 수 있는 property와 method를 가지고 있다.
- 프로토타입 상속은 특정 프로토타입 객체에 연결된 모든 객체는 그 프로토타입에서 정의된 property와 method를 사용할 수 있음을 의미한다.
- 예를 들어
Array.prototype
은 자바스크립트에서 만든 모든 배열의 프로토타입 객체이다. 즉 모든 배열은 Array.prototype
에 있는 모든 method를 상속받는다.
- 우리가 이때까지 forEach, map과 같은 method를 정의하지 않아도 배열의 method로 사용할 수 있는 동작 원리이다.
- 배열을 선언하고 콘솔로 찍어보면 배열이 우리가 사용했던 methode들이 포함된 prototype에 연결된 것을 볼 수 있다. 저 prototype이 바로
Array.prototype
이다.
클래스 상속과 프로토타입 상속의 차이
- 클래스 상속은 클래스가 다른 클래스로부터 상속받는 것을 의미한다.
- 프로토타입 상속은 객체가 자신과 연결된 프로토타입의 property와 method를 사용할 수 있음을 의미한다.
- 전통적인 클래스에서는 method가 인스턴스로 복사되지만, 프로로타입 상속은 프로토타입 객체와 연결된 객체에 method를 위임한다.
객체 생성 방법
자바스크립트에는 클래스 개념이 없기 때문에 별도의 객체 생성 방법이 존재한다.
- 객체 리터럴
- 생성자 함수 생성자 함수 정리글
- 생성자 함수와 new
키워드를 통해 인스턴스를 생성할 수 있다.
- 이때 생성자 함수는 클래스이자 생성자(constructor)의 역할을 한다.
- ES6 Class Class 정리글
- ES6에 도입된 class는 자바스크립트에서 OOP를 구현하는 현대적인 방법이다.
- 주의할 점은 도입된 class문법은 우리가 알고 있던 전통적인 class가 아닌 생성자 함수의 syntax sugar라는 사실이다. 생긴 모습만 class이고 실제 동작은 생성자 함수와 같으며 프로토타입 상속을 이용한다.
- Object.create()
- 객체를 프로토타입 객체에 연결하는 가장 쉽고 직관적인 방법이다.
참고
https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object-oriented_programming
https://poiemaweb.com/js-object-oriented-programming
https://www.udemy.com/course/the-complete-javascript-course/