[코드스테이츠 Day 26] 객체 지향 자바스크립트 / 함수 분리와 모듈화

Strawberry Oolong Tea·2021년 10월 5일
0

TODAY I LEARNED

목록 보기
35/51
post-thumbnail
post-custom-banner

객체 지향 프로그래밍(OOP, Object-oriented Programming)

데이터와 기능을 한 곳에 묶어서 처리하는 방법으로,
하나의 모델이 되는 청사진(blueprint)을 만들고
그 청사진을 바탕으로 하는 객체(object)를 만드는 프로그래밍 패턴을 말한다.

  • OOP는 프로그램 설계 철학 중 하나
  • OOP는 객체로 그룹화된다
  • 4가지 주요 개념(캡슐화, 상속, 추상화, 다형성)을 통해 재사용성을 얻을 수 있다

객체 메소드 호출하기

singleton 패턴으로 구현한 counter

let counter = {
  value: 0,
  // this는 counter를 가리킨다
  increase: function () {
    this.value++;
  },
  decrease: function () {
    this.value--;
  },
  getValue: function () {
    return this.value;
  }
}

singleton 패턴은 단 하나의 객체를 만든다

counter.increase(); // value: 1
counter.increase(); // value: 2
counter.increase(); // value: 3
counter.decrease(); // value: 2
counter.getValue(); // 2

singleton 패턴 ❓

소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다.

클로저 모듈 패턴으로 구현한 counter

function makeCounter() {
  return {
    value: 0,
    // this는 makeCounter가 리턴하는 익명의 객체
    increase: function () {
      this.value++;
    },
    decrease: function () {
      this.value--;
    },
    getValue: function () {
      return this.value;
    }
  }
}

클로저 모듈 패턴을 사용하면 매번 새로운 객체를 생성할 수 있다.

let counter1 = makeCounter();
counter1.increase(); // value: 1
counter1.getValue(); // 1

let counter2 = makeCounter();
counter2.decrease(); // value: -1
counter2.decrease(); // value: -2
counter2.getValue(); // -2

객체 지향 자바스크립트

모델의 청사진을 class라 하고 class를 바탕으로 한
객체를 instance 객체라고 한다.

  • 하나의 객체는 속성과 메소드를 포함하며
  • 내장 타입인 object와 다르게 class라고 한다
  • 자바스크립트에서 클래스는 함수의 한 종류이다

클래스 class

클래스는 일종의 원형(original form)으로,
객체를 생성하기 위한 아이디어나 청사진을 말한다.
클래스는 객체를 만들기 위한 생성자(constructor) 함수를 포함한다.

클래스를 정의하는 방법

  • 대문자로 시작하는 일반명사로 함수명을 작성한다
  • 클래스명과 함께 class 키워드를 사용한다
function SaladBowl(brand, capacity, color) {
  // 인스턴스가 만들어질 때 실행되는 코드
}

class 키워드를 이용해 정의하는 방법

class SaladBowl {
  constructor(brand, capacity, color) { // 생성자(constructor) 함수
    // 생성자 함수는 리턴값을 만들지 않는다
    // 인스턴스가 만들어질 때 실행되는 코드
  }
}

속성의 정의

// ES5
function SaladBowl(brand, capacity, color) {
  this.brand = brand;
  this.capacity = capacity;
  this.color = color;
}

// ES6
class SaladBowl {
  constructor(brand, capacity, color) {
    this.brand = brand;
    this.capacity = capacity;
    this.color = color;
  }
}

this ❓

함수가 실행될 때 해당 scope마다 생성되는
고유한 실행 컨텍스트 (execution context)를 말하며
new 키워드로 인스턴스를 생성했을 때의 해당 인스턴스 객체를 의미한다.
parameter로 넘어온 brand, capacity, color 등은
인스턴스 생성시 지정하는 값이고 이를 this에 할당하는 것은
만들어진 인스턴스에 해당 brand, capacity, color
부여하겠다는 의미이다.

메소드의 정의

// ES5
function SaladBowl(brand, capacity, color) { /* CODE */ }

SaladBowl.prototype.put = function () {
  // 샐러드 재료를 담는 코드
}

SaladBowl.prototype.mix = function () {
  // 샐러드 재료를 섞는 코드
}

// ES6
class SaladBowl {
  constructor(brand, capacity, color) { /* CODE */ }
  
  put() {
   // 샐러드 재료를 담는 코드
  }
  
  mix() {
   // 샐러드 재료를 섞는 코드
  }
}

인스턴스 객체

자바스크립트에서 사용하는 용어와 별개로 클래스를 통해 만들어진 객체를 말하며
각각의 인스턴스는 클래스의 고유한 속성과 메소드를 갖는다.

인스턴스 객체를 생성하는 방법

  • new 키워드를 사용한다
  • 클래스에 속성과 메소드를 정의하고 인스턴스에서 이용한다
let pyrex = new SaladBowl('Pyrex', '16oz', 'Blue');
let leCreuset = new SaladBowl('Le Creuset', '48oz', 'Orange');
let fissler = new SaladBowl('Fissler', '60oz', 'Clear');

인스턴스에서의 클래스 사용

let pyrex = new SaladBowl('Pyrex', '16oz', 'Blue');
pyrex.capacity; // '16oz'
pyrex.mix(); // pyrex의 샐러드 재료를 섞습니다

let fissler = new SaladBowl('Fissler', '60oz', 'Clear');
fissler.color; // 'clear'
fissler.put(); // fissler에 샐러드 재료를 담습니다

클래스로 구현한 counter

class Counter {
  // 생성자 호출을 할 경우 this는 new 키워드로 생성한 Counter의 인스턴스
  constructor() {
    this.value = 0;
  }
  increase() {
    this.value++;
  }
  decrease() {
    this.value--;
  }
  getValue() {
    return this.value;
  }
}

let counter1 = new Counter(); // 생성자 호출

OOP Basic Concepts

  • Encapsulation (캡슐화)
  • Inheritance (상속)
  • Abstraction (추상화)
  • Polymorphism (다형성)

캡슐화 Encapsulation

  • 데이터(속성)와 기능(메소드)을 하나의 단위로 묶는 것
  • 내부 데이터나 내부 구현이 외부로 노출되지 않도록 하는 은닉화의 특징을 포함한다
  • 즉, 구현은 숨기고 동작은 노출시킨다
  • 느슨한 결합에 유리하고 수정에 용이하다

상속 Inheritance

  • 부모 클래스의 특징을 자식 클래스가 물려받는 것을 말한다
  • 기본 클래스(base class)의 특징을 파생 클래스(derive class)가 상속받는다고도 할 수 있다

추상화 Abstraction

  • 복잡한 내부 구조를 단순화하여 노출시키는 것을 말한다
  • 추상화를 통해 인터페이스를 단순화할 수 있다

다형성 Polymorphism

  • 다양한 형태를 가질 수 있다는 의미로
  • 하나의 동작을 다른 형태로 수행하는 방법을 제공한다
  • 동일한 메소드에 대해 객체의 특성에 맞게 달리 작성하는 것이 가능하다

클래스와 프로토타입

프로토타입 Prototype

원형 객체를 의미한다.
자바스크립트는 프로토타입 기반 언어라 불리며
모든 객체들이 메소드와 속성을 상속받기 위한 템플릿으로써
프로토타입 객체를 가진다는 의미이다.

// Human 클래스 구현
class Human {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  sleep() {
    console.log(`${this.name}은 잠에 들었습니다`);
  }
}

// Human의 인스턴스인 strawberry
let strawberry = new Human('strawberry', 30);

클래스와 인스턴스, 프로토타입의 관계

Human === Human.prototype.constructor; // true
Human === strawberry; // false
Human.prototype.constructor === strawberry.__proto__; // false
Human.prototype === strawberry.__proto__; // true
Human.sleep === strawberry.sleep; // false
Human.prototype.sleep === strawberry.sleep; // true

프로토타입 체인

상위 객체로부터 속성과 메소드를 상속받을 수 있고
그 상위 객체 또한 더 위에 있는 객체로부터 속성과 메소를 상속받을 수 있다.
이를 프로토타입 체인이라 부르며 한 객체에서 다른 객체에 정의된
속성과 메소드를 사용할 수 있게 하는 근간이 된다.

ES6 클래스 문법

  • 클래스 선언은 호이스팅이 일어나지 않는다

extends

하위 클래스 생성시 extends 키워드를 사용해 상속받을 클래스를 명시한다.

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    this.name = {
      first,
      last
    };

  this.age = age;
  this.gender = gender;
  this.interests = interests;
  // subject와 grade는 Teacher의 특성
  this.subject = subject;
  this.grade = grade;
  }
}

super

constructor 함수 내부에 첫번째로 super() 연산자를 정의한다.
super() 연산자는 상위 클래스의 생성자를 호출하며
매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있다.

class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);

    // subject와 grade는 Teacher의 특성
    this.subject = subject;
    this.grade = grade;
  }
}
profile
Der Vogel kämpft sich aus dem Ei 🥚🐣 목표를 위해 끊임없이 자신의 세계를 깨뜨릴 수 있는 용감한 개발자가 되고 싶습니다.
post-custom-banner

0개의 댓글