클래스를 이용한 모듈화
객체지향 JavaScript
객체 지향 프로그래밍은 하나의 모델이 되는 청사진을 만들고, 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴이다.
여기에서 청사진을 바탕으로 한 "객체"는 인스턴스 객체(instance object), 줄여서 인스턴스라고 부른다.
"청사진"은 클래스라고 부른다.
객체를 만드는 방식은 일반적인 함수를 정의하는 것과 비슷하다.
function Car(color) {}
let avante = new Car("blue");
let mini = new Car("cyan");
let beetles = new Car("red");
이 때, 함수를 이용하는 방법이 조금 다르다.
그냥 실행하는 것이 아니라 new 키워드를 활용해서 만든다.
이는 새로운 인스턴스를 만드는 방법이다.
클래스를 그냥 함수로 정의할 때, 일반적인 다른 함수와 구분하기 위해서 암묵적인 규칙으로 앞 글자를 대문자로, 그리고 일반 명사로 만든다.
ES6의 class 활용
class Car {
constructor(brand, name, color) {
this.brand = brand;
this.name = name;
this.color = color;
}
}
ES6부터는 class 키워드가 도입되어서, 최근에는 함수를 이용하기보다는 주로 ES6의 class를 활용한다.
위 코드에서 보여지는 생성자(constructor) 함수는 인스턴스가 만들어질 때 실행되는 코드이다.
참고로 생성자 함수는 return 값을 만들지 않는다.
this 키워드
this라는 새로운 키워드를 발견할 수 있다.
객체지향 프로그래밍에서는 빠지지 않고 등장하는 요소이다.
this는 인스턴스 객체를 의미한다.
parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성 시 지정하는 값이며, 위와 같이 this에 할당한다는 것은, 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미이다.
메소드의 정의
class Car {
constructor(brand, name, color) {
/* 생략 */
}
refuel() {}
drive() {}
}
이렇게 간단하게 메소드를 정의할 수 있으며, 인스턴스에서의 활용은 다음과 같다.
let avante = new Car("hyundai", "avante", "black");
avante.drive();
avante.refuel();
잠시 새로 알게 된 용어들에 대해서 정리해보겠다.
개념 | 설명 |
---|---|
prototype | 모델의 청사진을 만들 때 쓰는 원형 객체 |
constructor | 인스턴스가 초기화될 때 실행하는 생성자 함수 |
this | 함수가 실행되는 scope마다 생성되는 고유한 실행 context |
Prototype
Object Oriented Programming
절차적 언어
- 초기의 프로그래밍 언어는 일반적으로 절차적 언어라고 부름
- 절차적 언어는 순차적인 명령의 조합
객체 지향 프로그래밍이라는 패러다임의 등장
- "클래스"라고 부르는 데이터 모델의 청사진을 사용해 코드를 작성하게 됨
- 현대의 언어들은 대부분 객체 지향의 특징을 갖고 있음(Java, C++, C# 등)
- JavaScript 또한 객체 지향으로 작성 가능
OOP
- OOP는 프로그램 설계 철학
- OOP의 모든 것은 "객체"로 그룹화
- OOP의 4가지 주요 개념을 통해 재사용성을 얻음
- "데이터와 기능이 함께 있다"는 원칙에 따라 메소드와 속성이 존재
클래스와 인스턴스
- 클래스는 일종의 원형(original form)으로, 객체를 생성하기 위한 아이디어나 청사진
- 인스턴스는 클래스의 사례(instance object)
- 클래스는 객체를 만들기 위한 생성자(constructor) 함수를 포함
OOP Basic Concepts
- Encapsulation (캡슐화)
- Inheritance (상속)
- Abstraction (추상화)
- Polymorphism (다형성)
캡슐화
- 데이터와 기능을 하나의 단위로 묶는 것
- 은닉(hiding) : 구현은 숨기고 동작은 노출
- 느슨한 결합(Loose Coupling) : 언제든 구현을 수정할 수 있음
→ 코드가 복잡하지 않게 해주며, 재사용성을 높인다.
추상화
- 내부 구현은 복잡하지만 노출되는 부분은 단순하게
- 내부 구조에 대해 생각하지 않게 해주는 간단한 인터페이스
→ 코드가 복잡하지 않게 해주며, 단순화된 사용으로 변화에 대한 영향력을 최소화한다.
상속
- 부모 클래스의 특징을 자식 클래스가 물려받음
- "base class"의 특징을 "derive class"가 상속받는다는 표현이 보다 적합
→ 불필요한 코드를 줄여 재사용성을 높인다.
다형성
- 같은 메소드를 다른 방식으로 구현할 수 있음
→ 동일한 메소드에 대해 조건문 대신 객체의 특성에 맞게 달리 작성할 수 있게 된다.
=> OOP는 사람이 세계를 보고 이해하는 방법을 흉내낸 방법 이론
클래스와 프로토타입
프로토타입 기반 언어
JavaScript는 흔히 프로토타입 기반 언어라 불린다.
모든 객체들이 메소드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다는 의미이다.
프로토타입 객체는 상위 프로토타입 객체로부터 메소드와 속성을 상속받을 수 있고, 그 상위 프로토타입 객체도 마찬가지이다.
이를 프로토타입 체인이라 부르며, 이는 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 해주는 근간이다.
정확히 말하자면, 상속되는 속성과 메소드들은 각 객체가 아니라 생성자의 prototype이라는 속성에 정의되어 있는 것이다.
JavaScript가 가지는 객체 지향 언어로서의 한계점
은닉화(private 키워드)의 한계
Java나 TypeScript 언어에는 클래스 내부에서만 쓰이는 속성 및 메소드를 구분시키기 위해 private이라는 키워드를 제공한다.
다음은 TypeScript에서 private을 활용하는 예시 코드이다.
class Animal {
private name: string;
constructor(theName: string) {
this.name = theName;
}
}
new Animal("Cat").name;
// Property 'name' is private and only accessible within class 'Animal'.
추상화(interface 키워드) 기능의 부재
마찬가지로 TypeScript 언어는 interface를 구현해놓았지만 JavaScript에는 존재하지 않는 기능이다.
다음은 TypeScript에서 인터페이스를 활용한 예시이다.
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}
}
'JavaScript > Vanilla' 카테고리의 다른 글
고차함수 (0) | 2021.07.27 |
---|---|
DOM (Document Object Model) (0) | 2021.07.24 |
객체의 얕은 복사와 깊은 복사 (0) | 2021.07.24 |
Hoisting (0) | 2021.07.24 |
Spread와 Rest 문법 (0) | 2021.07.24 |