TIL 2020-12-09 (객체 지향 프로그래밍)

nyongho·2020년 12월 9일
0

JavaScript

목록 보기
14/23
post-thumbnail

객체 지향 프로그래밍 (Object Oriented Programming)


TIL List

  • 객체 지향 프로그래밍 (Object Oriented Programming) 의 정의
  • JavaScript 에서 Object 를 생성하는 3가지 방법
  • JavaScript 가 Prototype 기반 언어인 이유

1) 객체 지향 프로그래밍 (OOP)

객체지향 프로그래밍은 실제 세계에 기반한 모델을 만들기 위해 추상화를 사용하는 프로그래밍 패러다임이다. 객체지향 프로그래밍은 modularity, polymorphism, encapsulation을 포함하여 이전에 정립된 패러다임들부터 여러가지 테크닉들을 사용한다. 오늘날 많은 유명한 프로그래밍 언어(자바, 자바스크립트, C#, C++, 파이썬, PHP, 루비, 오브젝트C)는 객체지향 프로그래밍을 지원한다.

초기 프로그래밍 방식은 절차적 프로그래밍 방식이었다. 즉, 입력을 받아 명시된 순서대로 처리한 다음, 그 결과를 내는 것뿐이라는 생각이 지배적이었다는 것이다.

하지만 이러한 방식에는 여러가지 비효율성이 따랐는데 간단하게 예를 들면 다음과 같다.

💡 전구 A와 전구 B에 전원을 공급하는 방법은 무엇이 있을까?

  1. 절차적 프로그래밍 방식

    전구 A에 전원을 공급하기 위한 발전기 A를 하나 두고 전구 A에 연결한다.

    전구 B에 전원을 공급하기 위한 발전기 B를 또 하나 두고 전구 B에 연결한다.

    ( 전원 공급을 위해 필요한 발전기 개수 : 2개 💡💡 🎛 🎛 )

  1. 객체 지향적 프로그래밍 방식

    전구 A에 전원을 공급하기 위한 발전기 A를 하나 두고 A에 연결한다.

    전구 B에 전원을 공급하기 위해 전구 A에서 전선을 하나 빼 전구 B에 연결한다.

    ( 전원 공급을 위해 필요한 발전기 개수 : 1개 💡💡 🎛 )

절차적 프로그래밍 방식에서는 어떤 방법을 사용하든 결과적으로 전구에 전원이 공급되기만 하면 된다.

하지만 객체 지향적 프로그래밍 방식에서는 전구에 전원을 공급하기 위한 가장 효율적인 방법을 사용한다.

차이점이 느껴지는가? 두 해결 방법 모두 같은 결과를 내놓지만 결국 그 외적인 요소 (에너지 효율 등) 에서는 객체 지향적 방식이 더 우위를 점할 수 밖에 없다.

만약, 어떠한 코드를 통해 같은 결과를 내놓는다해도 A 방법은 메모리를 30% 를 차지하고 B 방법은 메모리를 50%를 차지한다면 당연히 누구나 메모리 확보에 유리한 A 방법을 이용할 것이다.

이러한 비교를 통해 우리는 왜 객체 지향 프로그래밍을 사용해야 하는지 좀 더 이해가 될 수 있을 것이라 생각된다.


2) JavaScript 에서 Object (객체) 를 생성하는 방법

1. 기본객체 (Object() 객체) 의 생성자 함수 이용하는 방법

Object 객체를 생성하고, 생성한 객체에 새로운 속성을 추가하는 방법이다. 객체는 new 연산자를 이용해야 생성이 가능하다.

let myInfo = new Object();

myInfo.name = 'Yongho';

myInfo.gender = 'Male';

// typeof myInfo === "object"
// console.log(myInfo) -> {name: "Yongho", gender: "Male"}

2. 객체 리터럴을 이용하는 방법

1번에서는 객체를 생성하고, 그 객체에 특정 속성을 부여한 방식이었다.
하지만 객체 리터럴을 이용하면 객체를 만듦과 동시에 속성을 부여할 수 있다.

let myInfo = {
  name: 'Yongho'
  gender: 'Male'
};

// typeof myInfo === "object"
// console.log(myInfo) -> {name: "Yongho", gender: "Male"}

3. 생성자 함수를 이용하는 방법

객체를 생성하고 이를 new 키워드를 이용하여 특정 변수에 호출하면 해당 변수는 생성자 호출 역할을 맡게 된다.
❗️ 생성자 함수와 일반 함수를 구분하기 위해 생성자 함수는 대문자로 시작할 것을 권장한다.

let MyInfo = function (name, gender) {
  this.name = name
  this.gender = gender;
};

let myinfo = new MyInfo ('yongho', 'Male')
// typeof myinfo === "object"
// console.log(myinfo) -> MyInfo {name: "yongho", gender: "Male"}

3) JavaScript 에서 Prototype 이 가지는 의미

1. JavaScript 가 프로토타입 기반 언어임과 동시에 객체 지향 언어인 이유

앞서 자바스크립트는 객체 지향 언어라고 말했었다. 하지만 지금의 ES6 가 도입되기 전까지 자바스크립트는 다른 객체 지향 언어가 가지고 있는 Class 라는 개념이 없었다.

그 대신 자바스크립트에는 Prototype 이라는 것이 존재했다. 따라서 이러한 Prototype 이라는 것을 이용해 타 언어의 Class 처럼 상속을 흉내낼 수 있도록 했다. (ES6 에서 Class 문법이 추가됐지만, 자바스크립트는 여전히 Prototype 기반 언어이다.)

이러한 Prototype 을 언제 쓰는지 알아보도록 하자.

2. Prototype 을 활용한 객체 지향적 방법

function Person () {
  this.eyes = '2';
  this.nose = '1';
}

let steve = new Person();
let mason = new Person();

console.log(steve.eyes);  // => 2
console.log(steve.nose);  // => 1

console.log(mason.eyes); // => 2
console.log(mason.nose); // => 1

각각의 인물은 공통적으로 눈과 코라는 특성을 가지고 있는데 위에서 볼 수 있듯이 각 인물에게 그 특성을 2개씩 총 4개를 할당한다. 만약, 100명의 인물의 정보를 받아올 경우 100개씩 총 200개를 할당해야 한다.
이러한 절차적 프로그래밍 방식은 메모리 효율면에서 매우 비효율적이라고 이전에서 언급했다.

하지만 우리는 Prototype 을 이용해 우리가 원하는 객체 지향적 프로그래밍 방식으로 바꿀 수 있다.

function Person () {}

Person.prototype.eyes = 2;
Person.prototype.nose = 1;

let steve = new Person();
let mason = new Person();

console.log(steve.eyes);  // => 2

Person 이라는 함수에 기본적으로 eyes 와 nose 를 부여해 어디에서든지 공통적으로 사용할 수 있도록 함으로써 불필요한 공간을 방지해 메모리의 효율을 높이는 것이다.

사실 이미 이전에 한 번 자바스크립트의 객체 지향에 대해 블로깅을 한 적이 있었는데 프로토타입에 대해서는 자세하게 언급하지 않았었다. 그러므로 다음 블로깅에서는 이러한 prototype 이 어떻게 작동하는지, 그 원리는 무엇인지에 대해 다뤄보겠다!

profile
두 줄 소개

0개의 댓글