블로깅 주제
- Javascript 객체지향 프로그래밍
1. 지금 현재, 당신의 기분이나 느낌을 표현해 주세요.
- 어제가 대망의 섹션2 첫날이였으나, 고차함수를 공부하며 하루종일 머리가 뒤죽박죽했었다. 결국 너무 피곤해서 11시반쯤 잠들었던 것 같다..ㅠㅠ 특히 reduce! 개념이 확 와닿지 않아 헷갈렸다. 처음 배우는 거니까 헷갈린다고 생각하고 위안을 삼아야겠다. 이제 제법 추워졌다. 주말에 겨울 옷을 꺼내야겠다. 벌써부터 섹션2가 무섭지만, 즐겨야지!
2. 오늘 무엇을 학습한 내용 중 지금 떠올릴 수 있는 단어를 모두 나열해 주세요.
- 클로저 모듈패턴, 클래스/ 인스턴스, 객체지향 개념 네 가지, 프로토타입과 클래스, 프로토타입과 체인
3. 2에서 작성한 단어를 가지고, 오늘의 학습 내용을 설명해 보세요.
- 클로저 모듈 패턴
매번 새로운 객체 생성할 때 사용 가능
예시)
function makeCounter() {
let value = 0;
return {
increase: function() {
value++;
},
decrease: function() {
value--;
},
getValue: function() {
return value;
}
}
}
let counter1 = makeCounter()
counter1.increase()
counter1.getValue() // 1
let counter2 = makeCounter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2
⚠️ 메서드 호출 방식을 이용할 때에는 화살표 함수를 쓰지 않는다!
https://sewonzzang.tistory.com/21
- 클래스와 인스턴스
객체 지향 프로그래밍은 하나의 모델이 되는 청사진(blueprint)을 만들고, 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴
- 클래스(class) : 청사진
- 인스턴스(instance) : '청사진'을 바탕으로 하는 객체. 'new' 키워드를 사용하여 만듦.
- 클래스 내에서 생성자 함수는 하나만 있을 수 있다.
- 생성자 함수는 인스턴스 객체를 생성하고 초기화하는 특별한 메서드이다.
- 생성자 함수를 작성하지 않으면, 기본 생성자(default constructor)가 제공되며,
기본(base) 클래스일 경우는 기본 생성자는 비어있으며, 파생(derived) 클래스일 경우 기본 생성자는 부모 생성자를 부른다.
ex)
▷ 생성자(constructor) 함수는 return 값 x
class Car{
constructor(brand, name, color){
//인스턴스가 만들어질 때 실행되는 코드
}
}
▷ 클래스의 인스턴스
변수에 클래스의 설계를 가진 새로운 객체, 즉 인스턴스가 할당됨.
각각의 인스턴스는 클래스의 고유한 속성과 메서드를 가짐.
let avante = new Car('Hyundai','avante','black')
let mini = new Car('bmw','mini','white')
▶ 속성과 메소드 : 클래스에 속성과 메소드를 정의하고, 인스턴스에서 이용
this는 인스턴스 객체를 의미한다.
parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성 시 지정하는 값이며,
위와 같이 this에 할당한다는 것은, 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미이다.
class Car{
constructor(brand, name, color){
this.brand = brand;
this.name = name;
this.color = color;
}
refuel(){}
drive(){}
}
인스턴스 사용 예시)
let avante = new Car('Hyundai','avante','black')
avante.color; // 'black'
avante.drive(); // 'avante가 운전을 시작합니다.'
let mini = new Car('bmw','mini','white')
mini.color; // 'white'
mini.refuel(); // 'mini에 연료를 주입합니다.'
▶ 용어 정리
▶ ES5 문법
▶ ES6 문법
class Car{
constructor(brand, name, color){
this.brand = brand;
this.name = name;
this.color = color;
}
refuel(){
return `${this.name}에 연료를 주입합니다.`;
}
drive(){
return `${this.name}가 운전을 시작합니다.`;
}
}
클래스 문법 사용 예시)
class Counter {
constructor() {
this.value = 0; // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스입니다
}
increase() {
this.value++
}
decrease() {
this.value--
}
getValue() {
return this.value
}
}
let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1
- 객체지향 프로그래밍
▶ 객체지향의 기본 개념 네 가지
- 캡슐화
- 상속
- 추상화
- 다형성
1. 캡슐화 : 코드가 복잡하지 않게 만들고, 재사용성을 높임
1) 데이터와 기능을 하나의 단위로 묶는 것
데이터(속성)와 기능(메서드)들이 느슨하게 결합됨.
* 느슨한 결합: 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아닌, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것
ex) 마우스 구동
스위치가 눌리고, 전기 신호가 생겨서, 전선을 타고 흐르고.. 와 같은 전 과정을 이곳저곳에 나누어 작성하는 것이 아니라, 마우스의 상태를 속성(property)으로 정하고 클릭, 이동을 메서드(method)로 정해서 코드만 보고도 인스턴스 객체의 기능을 상상할 수 있게 작성하는 것
==> 느슨한 결합을 추구하는 코드 작성법
2) 은닉: 구현은 숨기고, 데이터는 노출시킴
은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것
따라서, 디테일한 구현이나 데이터는 숨기고, 객체 외부에서 필요한 동작(메서드)만 노출시켜야 함
은닉화의 특징을 살려서 코드를 작성하면 객체 내 메서드의 구현만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있음
3) 느슨한 결합에 유리: 언제든지 구현을 수정할 수 있음
2. 상속 : 불필요한 코드를 줄여 재사용성을 높임
기본 클래스(base class) 즉 부모 클래스의 특징을 파생 클래스(derived class) 즉 자식 클래스가 상속받음
3. 추상화 : 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화
내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념
==> 속성과 메서드의 이름만 노출시켜서 사용을 단순화한다!
클래스 정의 시, 메서드와 속성만 정의한 것을 인터페이스라고 부름 ==> 추상화를 통해 인터페이스가 단순해짐
너무 많은 기능들이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있음
ex) '전화'라는 객체
전화라는 객체가 있다면, 그 안에는 스피커와 마이크가 존재하고, 서킷 보드 등이 존재하는 등 내부 구현이 되어 있음
그러나 실제로 우리가 사용할 때에는, 이러한 존재에 대해서는 생각하지 않고 단순히 수화기를 들고 버튼을 눌러서 해결하는 것으로 인터페이스(interface)를 단순화할 수 있음
추상화 vs 캡슐화
캡슐화가 코드나 데이터의 은닉에 포커스가 맞춰져있다면,
추상화는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 포커스 맞춰져 있음
4. 다형성 : 동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해짐
똑같은 메서드라 하더라도, 다른 방식으로 구현될 수 있음
- Javascript와 타 객체지향 언어 차이점
1. 은닉화(private)의 한계
Java나 TypeScript라는 프로그래밍 언어는 클래스 내부에서만 쓰이는 속성 및 메서드를 구분시키기 위해 private이라는 키워드를 제공
이러한 은닉화를 도와주는 기능이 JavaScript에서는 널리 쓰이지 않음
ex) 'name' 속성에는 private 키워드가 붙어 있어서, 클래스 내부에서만 사용 가능
// TypeScript 문법입니다.
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'.
JavaScript에서는 은닉화를 돕기 위해서 일반적으로 클로저 모듈 패턴을 사용
클래스/인스턴스 형태로 만들 때에는 ES2019부터 #이라는 키워드가 도입되었음
2. 추상화(interface)기능의 부재
Java나 TypeScript 언어는 언어의 주요 기능으로 interface를 구현해 놓음 ==> JavaScript에는 존재하지 않는 기능
ex) 인터페이스와 구현이 따로 정의되어 있음
// 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) {}
}
- 프로토타입과 클래스
프로토타입(Prototype) : 원형 객체
★ 상속되는 속성과 메소드들은 각 객체가 아니라 '객체의 생성자'의 'prototype'이라는 속성에 정의되어 있는 것
★ prototype에 constructor도 포함됨
OOP 패턴으로 구현한 Human 예시)
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
let kimcoding = new Human('김코딩', 30);
// 실습해보세요
Human.prototype.constructor === Human; // true
Human.prototype === kimcoding.__proto__; // true
Human.prototype.sleep === kimcoding.sleep; // true
▶ Human이라는 클래스와 인스턴스, 그리고 프로토타입의 관계
ex) Array
배열(arr)은 Array 클래스의 인스턴스이며, 프로토타입에는 다양한 메서드가 존재함
https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes
'코드스테이츠 SEB FE 41기 > Section 별 내용 정리' 카테고리의 다른 글
section2/unit3/[JS/Node] 비동기(9/23) (1) | 2022.09.23 |
---|---|
section2/unit2/Javascript 객체지향 프로그래밍(9/22) (1) | 2022.09.21 |
section2/unit1/Javascript 고차함수(9/20) (2) | 2022.09.20 |
section1/unit12/Coz’ Mini Hackathon(9/15~16) (0) | 2022.09.16 |
section1/unit11/DOM(9/14) (0) | 2022.09.14 |