부트캠프 이머시브 10일차 TIL입니다.
오늘은 OOP, Inheritance Pattern 등에 대해서 학습을 해봤습니다.
일반적으로 Programming Language는 다음과 같이 3가지가 있다고 하는데요.
- Machine Language(기계어) : 0과 1로 구성된 언어(컴퓨터가 이해)
- Assembly Language(어셈블리어) : 기본적인 명령어를 통하여 컴퓨터에게 명령을 지시하는 언어
- High-Level Language : 어셈블리어를 가지고 어셈블리어로 여러 함수들을 만들어서 함수들을 사용하게 만들게 끔 구성된 언어(JS & Python은 C 언어로 만들어졌음; 지금의 우리가 사용하는 언어)
당연히 고급 언어일 수록 여러 환경에서 쓸 수 있기 때문에 어셈블리어나 기계어보다는 조금 비효율적일 수 있으나, 당연히 훨씬 더 편리하겠죠..?
고급 언어에도 Procedural Langauges, Object Oriented Language 등으로 다양한 종류가 있는데요...
오늘은 OOP에 대해서 한번 정리를 해보겠습니다.
1. OOP에 대한 정리
1) OOP의 기본 개념 정리
- OOP(객체지향 프로그래밍)이란 문제를 여러 개의 객체 단위로 나눠서 작업하는 방식임
- "사람이 세계를 보고 이해하는 방법을 흉내내 방법론"이라고 할 수 있으며 일종의 프로그래밍 철학이라고 할 수도 있음(어떤 방식으로 프로그래밍을 할 것인가..)
2) OOP의 4가지 특성
let baseSalary = 30_000;
let overtime = 10;
let rate = 20;
function getWage(baseSalary, overtime, rate) {
return baseSalary + (overTime * rate);
}
let employee = {
baseSalary : 30_000,
overtime : 10,
rate: 20,
getWage: function() {
return this.baseSalary + (this.overtime * this.rate);
}
}
employee.getWage();
- Encapsulation(캡슐화)
- 예시의 baseSalary, getWage 등과 같이 관련된 속성(변수, method)들을 모두 클래스 혹은 객체 안에 모아두는 것(캡슐화)
- 코드의 복잡도를 낮추고, 재사용성을 높임
- Inheritance(상속)
- 부모의 특징을 자식이 물려받는 경우
- 중복 코드를 줄임
- 예시 : HTMLDivElement는 _proto(혹은 부모)로 HTMLElement를 가지고 있는데, 이 경우
HTMLDivElement는 HTMLElement의 HTMLElement.focus 메서드 혹은 HTMLElement.title과 같은 속성을 똑같이 상속 받음
- Abstraction(추상화)
- 객체의 핵심적인 개념/기능만 묶어서 추출함
- 코드를 보다 쉽게 이해할 수 있고, 사용자에 의한 수정으로 영향을 받을 확률이 적음
- Polymorphism(다형성)
- 같은 타입(부모 클래스)이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질임
- Ugly한 Switch/Case Statement를 Refactoring 해줌
2. Instantiation Patterns에 대한 정리
JavaScript에 Class라는 개념이 존재하기 전에 사용되던 4가지 Class 선언 방식은 다음과 같음.
1) Functional 패턴
const Car = function() {
const someInstance = {};
someInstance.position = 0;
someInstance.move = function() {
this.position += 1;
};
return someInstance;
};
let car1 = Car();
let car2 = Car();
car1.move();
- 생성자 함수(Car)에 Class와 같이 모든 속성값과 메서드를 할당
- 새로운 변수에 Car()를 할당하여 someInstance가 return된 값을 할당
- Functional의 경우 각 Instance마다 모든 메소드가 할당되기 때문에 각 Instance에 Method의 수만큼의 메모리가 소요되기 때문에 비효율적임
2) Functional Shared 패턴
const extend = function(to, from) {
for(let key in from) {
to[key] = from[key];
}
};
const someMethods = {};
someMethods.move = function() {
this.position += 1;
};
const car = function(position) {
const someInstance = {
position: position
}
extend(someInstance, someMethods);
return someInstance;
- 공통된 함수의 경우 별도로 선언하여 Class격 Function에서 이용
- 이 경우 함수가 공유되기 때문에 Functional 패턴과는 달리 각 Instance 별로 함수를 저장하는 메모리를 줄임으로서 메모리 효율이 좋아짐
3) Prototypal 패턴
const someMehtods = {};
someMethods.move = function() {
this.position += 1;
};
const Car = function(position) {
let someInstance = Object.create(someMethods);
someInstance.position = position;
return someInstance;
}
let car1 = Car(5);
let car2 = Car(10);
- Object.create는 프로토타입으로 하는 객체를 생성해주는 함수임
- Functional Shared 패턴과는 달리 공유하는 extend 함수를 이용하지 않고 Object.create으로 객체를 생성한 후 position key를 추가해주고 Parameter로 position의 값을 받거나, 아니면 미리 만들어둔 someMethods.move를 이용하여 postion을 업데이트 함.
4) Pseudoclassical 패턴
const Car = function(position) {
this.position = position;
};
Car.prototype.move = function() {
this.position += 1;
};
let car1 = new Car(5);
let car2 = new Car(10);
- 모든 함수는 prototype이라는 특수한 속성을 가지고 있으며, prototype은 Class Constructor의 Property이고 proto는 Class Instance의 속성임(이를 제외하면 둘다 사실상 갖다고 보면됨)
- Class를 Function으로 구현하고, 이후 해당 Function prototype에 Method를 추가하는 방식
- new 키워드를 이용하여 인스턴스격의 객체를 생성
3. Prototpye에 대한 정리
1) 기본 개념 정리
class Human {
constructor(name) {
this.name = name;
}
sleep(){
console.log('sleeeeeping');
}
}
let steve = new Human('steve');
class Student extends Human {
constructor(name){
super(name)
}
learn() {
console.log(`${this.name} likes learning`;
}
}
let john = new Student('john');
john.learn();
john.sleep();
- Prototype : 모델의 청사진을 만들 때 쓰는 원형 객체(Original From) aka. 해당 클래스 원형에 내장되는 함수들
-prototype은 Class Constructor의 속성(메서드) proto는 Class Instance(혹은 child)의 속성(메서드)
- prototype은 할당이 가능(Assignable)함
- Constructor : Instance가 초기화될 때 실행하는 생성자 함수
- this : 함수가 실행될 때, 해당 Scope마다 생성되는 고유한 Execution Context
- new 키워드로 생성한 Instance의 경우 해당 Instance가 this 값이 됨
- super
- Student가 Human의 속성들을 그대로 받아올 경우
extends와 super를 이용하여 가져올 수 있음.
- 자식 Class(Student)가 부모(Human)의 arguments를 그대로 가져온 것이라면 constructor() 자체를 지워도 됨
2) JavaScript Prototpye의 기본 개념 정리
- OOP의 예시로는 Java, Python 등이 있으며, 모든 OOP 언어들은 Class라는 개념이 존재하며, 그 Class로 Instance들을 생성할 수 있음
- JS는 protoㅏtype 기반 OOP이며, new 키워드를 이용해 Class와 Instance 개념을 흉해낼 수 있음
- ES6부터는 JS에 Class라는 문법이 추가되었지만, 언어의 기반 자체가 바뀐 것은 아님
3) Class와 Object의 차이
- Class는 프로토타입으로, 객체를 만들기 위한 아이디어나 청사진이라고 보면 됨
- Object는 Class의 Instance임