Frontend/Today I Learned

[JS] 객체 지향 언어 : 프로토타입 vs. 클래스

joycie416 2024. 12. 16. 22:32

인공지능에 대한 관심이 커지면서 파이썬 사용이 늘어났다. 그러면서 많이 들었던 말 중 하나로 '파이썬은 객체 지향 언어'가 있다. 파이썬 외에도 Java, C++ 등도 객체 지향 언어이고, 웹 개발에 많이 쓰이는 JavaScript도 객체 지향 언어이다. 그런데 파이썬, Java, C++과 JS은 완전히 같은 객체 지향 언어는 아니다.

 

먼저 JS는 프로토타입 기반이고 파이썬, Java, C++은 클래스 기반 객체 지향 언어(Object-Oriented Programming, OOP)이다.

 

01 객체 지향 프로그래밍 (OOP) vs. 절차 지향 프로그래밍 (Procedural Programming)

객체 지향 프로그래밍은 프로그램이 해결해야할 문제를 작은 부분들로 나누고, 각 부분을 데이터(속성)와 그 데이터와 관련된 기능(메서드)을 가진 '객체'로 만든다. 즉 현실 세계의 객체를 모델링해서 프로그램을 구성한다.

절차 지향 프로그래밍은 레시피를 따르는 것처럼 여러 개의 순서대로 진행되는 절차(함수나 명령)들로 이루어진 프로그램을 만든다. 즉 프로그램을 명령의 순서와 절차로 본다.

 

모두의 연구소의 예제를 살펴보면 비교가 쉽다.

절차 지향 프로그래밍 예제

더보기
# 절차 지향 프로그래밍 예제

# 계좌 잔액
account_balance = 0

# 잔액 확인 함수
def check_balance():
    global account_balance
    print(f"현재 잔액은 {account_balance}원 입니다.")

# 입금 함수
def deposit(amount):
    global account_balance
    account_balance += amount
    print(f"{amount}원을 입금했습니다.")

# 출금 함수
def withdraw(amount):
    global account_balance
    if account_balance >= amount:
        account_balance -= amount
        print(f"{amount}원을 출금했습니다.")
    else:
        print("잔액이 부족합니다.")

# 함수 사용 예시
check_balance()   # 현재 잔액은 0 원 입니다.
deposit(50000)   # 50000 원을 입금했습니다.
check_balance()   # 현재 잔액은 50000 원 입니다.
withdraw(20000)   # 20000 원을 출금했습니다.
check_balance()   # 현재 잔액은 30000 원입니다.

객체 지향 프로그래밍 예제

더보기
# 객체 지향 프로그래밍 예제

class BankAccount:
    def __init__(self):
        self.balance = 0  # 계좌의 초기 잔액을 0으로 설정
    
    def check_balance(self):
        print(f"현재 잔액은 {self.balance}원 입니다.")
    
    def deposit(self, amount):
        self.balance += amount
        print(f"{amount}원을 입금했습니다.")
    
    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
            print(f"{amount}원을 출금했습니다.")
        else:
            print("잔액이 부족합니다.")

# 객체 사용 예시
account = BankAccount()   # 객체 생성
account.check_balance()   # 현재 잔액은 0 원 입니다.
account.deposit(50000)   # 50000 원을 입금했습니다.
account.check_balance()   # 현재 잔액은 50000 원 입니다.
account.withdraw(20000)   # 20000 원을 출금했습니다.
account.check_balance()   # 현재 잔액은 30000 원입니다.

 

두 예제를 살펴볼 때 가장 큰 차이점은 다음과 같다.

절차 지향 코드는 기능 중심으로 구성되어 있고, 객체 지향 코드는 상태와 행위를 하나의 단위로 묶어 관리한다.

 

따라서 객체 지향 프로그래밍은 여러 개체가 서로 다른 행동을 해야 할 때, 코드의 재사용성과 확정성을 크게 향상시킬 수 있다는 장점이 있다.

 

02 클래스 기반 vs. 프로토타입 기반

그러면 클래스 기반과 프로토타입 기반 객체 지향 언어는 어떤 차이점이 있을까?

 

02-1 클래스 기반 객체 지향 언어

클래스 기반 객체 지향 언어는 객체를 정의하기 위해 `class`라는 구조를 사용한다. 클래스를 통해 객체의 속성(attribute, property)과 행위(method)를 정의하고, 이를 기반으로 인스턴스(instance)를 생성한다. 쉽게 이야기하면 `class`는 객체의 구조와 기능에 대한 청사진 역할을 한다고 볼 수 있다.

 

클래스 상속을 통해 다른 클래스의 속성와 메서드를 재사용하거나 확장할 수 있으며 오버라이딩도 가능하다. 클래스 내부 데이터와 메서드를 캡슐화하겨 객체의 상태를 보호하며, 기본적으로 동적으로 속성이나 메서드를 추가하는 것은 불가능하다. (가능하지만 권장하지 않는다.)

 

`class`는 계급이라는 뜻 그대로, 상속을 통해 계층 구조를 쉽게 파악할 수 있는 장점이 있다.

 

02-2 프로토타입 기반 객체 지향 언어

프로토타입 객체 지향 언어는 객체에 `prototype`이라는 속성이 존재해, 프로토타입 체인을 통해 다른 객체의 속성과 메서드를 상속받는다. 클래스 기반 언어처럼 다른 프로토타입의 속성과 메서드를 재사용하거나 확장할 수 있고 오버라이딩도 가능하다. 하지만 프로토타입을 잘 이해하지 못하거나 체계적으로 구조화되지 않으면 혼란스러울 수 있다.

 

JS에서는 기본적으로 함수를 통해 객체를 생성하며 `prototype`이라는 속성을 통해 다른 프로토타입 객체와 연결된다. JS에서는 ES6부터 `class`가 추가됐지만, 프로토타입 기반으로 동작하며 클래스 기반 언어 사용자들 위해 추가되었다. 클래스 기반 언어와 달리 동적으로 기존 객체에 속성이나 메서드를 추가할 수 있다.

 

`prototype`이라는 단어 그대로, 해당 객체의 원형, 원조, 기원을 의미한다고 생각하면 좋을 것 같다.

 

02-3 표로 비교하기

클래스 기반 언어와 프로토타입 기반 언어를 표로 비교해보면 아래와 같다.

특징 프로토타입 기반(JS) 클래스 기반
유연성 동적이고 유연한 설계. 제한 없이 수정 및 확장 가능. 제한적이며 명확성 중심. 설계도를 따르는 구조.
상속 프로토타입 체인을 통한 동적 상속. 클래스 기반 명시적 상속.
런타임 조작 자유롭게 가능. 가능하지만 지양.
코드 가독성 자유도는 높지만 구조화되지 않으면 혼란스러울 수 있음. 읽기 쉽고 구조화된 설계를 기본으로 함.
철학 개발자가 원하는 대로 할 수 있다. 명확성과 안정성이 우선이다.

 

 

 


참고 문서

 

객체 지향 쉽지 않다면? OOP 입문자를 위한 친절한 가이드

프로그래밍 패러다임으로 주로 언급되는 절차 지향 프로그래밍(Procedural Programming)과 객체 지향 프로그래밍(Object-Oriented Programming, OOP)에 대해, 예제 코드로 비교해보는 친절한 가이드입니다.

modulabs.co.kr

 

[JavaScript]객체지향 프로그래밍 (클래스 기반 vs 프로토타입 기반)

🍊 객체지향 프로그래밍객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 현실에 존재하는 객체를 소프트웨어에 표현하기 위한 방법이다. 프로그래밍에서 필요한 데이터를 추상화 시켜 상태

breath-in317.tistory.com

 

'Frontend > Today I Learned' 카테고리의 다른 글

[JS] 프로토타입 Prototype  (0) 2024.12.17
[JS] 클로저(closure)  (1) 2024.12.10
[JS] this  (0) 2024.12.02
[Next.js] Zustand 사용하기  (2) 2024.11.28
[React] TanStack Query로 custom hook 만들기  (0) 2024.10.31