본문 바로가기

코드스테이츠 SEB FE 41기/Section 별 내용 정리

section2/unit2/Javascript 객체지향 프로그래밍(9/21)

반응형

블로깅 주제

  • 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

 

[javascript] 화살표 함수 (()=>, Arrow Function)

화살표 함수? this를 가지지 않습니다. arguments를 지원하지 않습니다. new와 함께 호출할 수 없습니다. super가 없습니다. 화살표 함수(Arrow function)는 function 키워드 대신 화살표(=>) 를 사용하여 보다..

sewonzzang.tistory.com


- 클래스와 인스턴스

객체 지향 프로그래밍은 하나의 모델이 되는 청사진(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 문법

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) 은닉: 구현은 숨기고, 데이터는 노출시킴

은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것

따라서, 디테일한 구현이나 데이터는 숨기고, 객체 외부에서 필요한 동작(메서드)만 노출시켜야 함

은닉화의 특징을 살려서 코드를 작성하면 객체 내 메서드의 구현만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있음

더 엄격한 클래스는 속성의 직접적인 접근을 막고, 설정하는 함수(setter), 불러오는 함수(getter)를 철저하게 나누기도 함
 

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

 

Object prototypes - Web 개발 학습하기 | MDN

Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용합니다. 본 문서에서는 프로토타입 체인이 동작하는 방식을 설명하고 이미 존재하는 생성자에 메소드를 추가하기 위해 프

developer.mozilla.org

 

반응형