- Published on
자바스크립트 프로토타입 - 암기가 아닌 이해하기 1편
이번 포스팅은 자바스크립트는 왜 프로토타입을 선택했을까를 읽고,
관련 내용을 쉽게 이해하고, 정리하기 위한 글입니다.
2편(完)
👉프로토타입이란 무엇이라고 생각하시나요?
기술 면접 때, 위 질문을 대게 한 번쯤은 받아 본 경험이 있을 것이다. 나 역시 해당 질문을 받아 본 경험이 있었고, 여러 면접 예상 질문을 모아놓은 리스트에서도 빈출 질문으로 명시되어 있다.
면접을 앞두고 책, GPT, 답변 자료 등을 총합해 노션에 내가 답변할 해당 내용을 열심히 정리하고 외워서 면접을 봤다. 기계처럼, 습관처럼 말하기 위해 열심히 암기했다.
프로토타입은.. 자바스크립트에서 객체가 상속을 통해 다른 객체의 속성이나 메서드를 공유하는 기법으로..
면접이 끝나고 열심히 암기했던 프로토타입에 대한 기억은 따로 의식하지 않아도 자연스럽게 휘발되었다. 그렇게 다른 면접 날짜가 잡히게 되면, 나는 또다시 해당 내용을 기계처럼 암기하기 위해 노력했다.
지금까지 이 프로세스를 반복하며 이를 자각하지 못했다. 비단 프로토타입만의 문제가 아니라 대부분의 기술적인 내용을 암기하기에 급급했었던 것 같다. 그렇기 때문에 면접 때 긴장해서 해당 내용을 잊어버리거나, 응용되는 다른 질문을 받게 되면 쉽게 답변하지 못했다.
그래서 이번 기회를 계기로 '프로토타입 원론'과의 연관성을 통해 프로토타입을 더 쉽고 확실하게 이해하고 정리하는 시간을 가지고자 한다.
'클래스 기반 객체지향'
프로토타입 기반 객체지향의 대척점 프로토타입 기반 객체지향과 클래스 기반 객체지향은 서로 대척점에 있다. 따라서 주요 원론을 비교해 보면 프로토타입을 더 쉽게 이해할 수 있다.
클래스 기반 객체지향 프로그래밍은 추상적인 청사진(클래스)을 이용해 구체적인 실체(객체)를 만드는 방식이다. 이 과정에서 클래스는 객체의 설계도 역할을 하며, 객체는 이 설계도를 바탕으로 만들어진다.
이해를 돕기 위해 라면을 예로 들어보자.
마트에서 라면을 살 때 우리는 '라면'이라는 추상적인 개념을 사는 것이 아니라 '신라면'이나 '오징어짬뽕' 같은 라면의 한 종류를 산다. 여기서 '라면'이라는 개념은 다양한 속성과 공통적인 조리 과정을 공유하는 추상적인 클래스와 같고, 실제로 구매하는 것은 신라면이나 오징어짬뽕 같은 구체적인 객체이다.
클래스 기반 객체지향의 대표적인 언어 중 하나로 Java가 있다. Java는 클래스를 사용하여 객체를 생성하고, 이를 통해 객체지향 프로그래밍의 주요 개념인 상속, 다형성, 캡슐화를 명확하게 구현할 수 있는 특징을 가지고 있다.
abstract class Ramen {
String name;
// 라면 끓이는 과정 (공통 메소드)
public void cookRamen() {
cook();
serve();
}
// 기본적인 조리 과정
private void cook() {
System.out.println("물을 끓이고 라면 사리를 넣습니다.");
System.out.println("건더기 스프를 넣습니다.");
}
private void serve() {
System.out.println(name + " 완성되었습니다. 맛있게 드세요!\n");
}
}
class ShinRamen extends Ramen {
public ShinRamen() {
this.name = "신라면";
}
}
public class Main {
public static void main(String[] args) {
Ramen ramen = new ShinRamen();
ramen.cookRamen();
}
}
라면의 예시를 Java로 구현하면, 우리가 흔히 접할 수 있는 클래스와 객체의 관계를 직관적으로 이해할 수 있는 간단한 코드가 된다.
프로토타입과 동일하게 클래스 기반 객체지향 또한 주요 원론이 존재하는데, 학창 시절 윤리와 사상을 배워봤다면 한 번쯤은 들어봤을 플라톤, 아리스토텔레스의 이론이다.
플라톤의 이데아론
추상적인 대상을 실체화하는 이 개념은 플라톤의 이데아 이론과 유사한데, 플라톤은 본질적이지만 추상적인 개념은 현실에 존재하지 않는다고 주장했다. 그렇기 때문에 우리가 만나는 것은 항상 구체적인 형태로만 존재한다는 것이다.
< 플라톤 - 이데아론을 동굴에 비유 >
인간은 그 실체를 보아야 한다는 주장
세상 만물은 동굴 벽에 비친 그림자에 불과하고 동굴 밖에 실체가 존재하며, 이와 같은 추상적인 개념은 객체지향 프로그래밍의 클래스와 유사하다. 클래스는 어떤 대상의 본질적인 속성을 정의하지만, 구체적인 실체는 아니다. 즉, '라면'이라는 클래스는 ‘이름, 가격, 칼로리’와 같은 라면의 본질적인 속성을 정의할 뿐, 직접 존재하는 것은 아니다.
아리스토텔레스 - 분류
플라톤의 제자인 아리스토텔레스는 이를 이어받아, 동일한 속성을 가진 개체들을 묶어 범주화하는 개념으로 발전시켰다. 아리스토텔레스는 '라면'이라는 본질적인 속성을 가진 여러 개체들이 존재할 수 있다고 보았고, 이러한 개체들을 분류하는 개념을 발전시켰다.
아리스토텔레스는 분리수거에 상당히 능했을 것이다. ( 추정 )
이는 객체지향 프로그래밍에서 클래스 기반의 분류 체계로 정착되었으며, 동일한 클래스를 기반으로 (신라면, 오징어 짬뽕과 같은) 다양한 인스턴스를 만들 수 있다.
따라서, 객체지향 프로그래밍에서 클래스는 플라톤의 이데아와 같은 추상적 존재로, 인스턴스는 아리스토텔레스의 분류된 실체와 같다고 볼 수 있다. 이러한 철학적 개념이 현재의 클래스 기반 객체지향 프로그래밍에 영향을 미친 것이다.
의미사용, 가족유사성 이론의 어떤 점을 착안했나
프로토타입 기반 객체지향은 의미사용, 가족유사성 이론은 프로토타입 기반 객체지향의 특정 개념을 대표하는 전형적인 예시로 기능하며, 이 전형적인 예시는 새로운 객체를 생성하는 데 사용된다. 이 두 가지 주요 원론을 이해하면 프로토타입의 동작 방식과 개념을 깊이 이해하는 데 큰 도움이 된다.
의미사용 이론
객체들은 특정 의미나 역할에 따라 사용되며,
그 의미가 상황에 따라 달라질 수 있다.
- 특정 객체가 사용되는 맥락에 따라 새로운 역할을 부여받아 다양한 의미를 가질 수 있다.
파리채는 원래 벌레를 잡는 용도로 만들어진 도구지만, 상황에 따라 파리채는 다른 의미를 가질 수 있다. 예를 들어, 훈육의 상징적 도구로 사용되기도 하며, 신체에서 손이 닿지 않는 곳을 긁을 때에도 사용될 수 있다. 이처럼 파리채라는 객체는 원래 용도인 '벌레 잡기' 외에도 여러 상황에서 다양하게 재해석될 수 있다.
프로토타입 기반 객체지향 프로그래밍에서의 활용
이 방식은 프로토타입 기반 객체지향 프로그래밍에서 객체들이 상황과 맥락에 따라 새로운 의미와 역할을 유연하게 취할 수 있게 하는 핵심 개념과 연결된다.
의미사용 이론은 고정된 클래스 구조에 얽매이지 않고, 객체가 상황에 따라 역할을 변경할 수 있다는 점에서 프로토타입 기반 객체지향 프로그래밍과 잘 맞아떨어진다. 프로토타입 기반에서는 공통된 프로토타입을 통해 동일한 기능이나 메서드를 공유하면서도, 객체가 각기 다른 상황에서 새로운 역할을 가질 수 있는 유연한 구조
를 제공한다.
앞서 예로 들었던 파리채처럼, 여러 상황에서 프로토타입을 기반으로 다양한 역할을 수행하는 인스턴스가 만들어질 수 있다. 이는 코드 중복을 줄이고, 확장성과 유연성을 극대화한다.
가족 유사성 이론
가족 구성원들이 서로 다른 외모적 특징을 가진다고 해도,
여전히 그들은 '가족'이라는 범주로 묶인다.
- 객체들이 공통적인 특징을 가지고 있으나
그 특징이 모두에게 동일하게 적용되지 않을 수 있다.
가족 유사성 이론에 대한 이해를 돕기 위해 강아지와 CCTV를 살펴보자. 공통적인 속성을 찾기 위해 고민했지만, 쉽게 공통점을 찾을 수 없을 것이다. 여기서 필자는 '집을 지킨다'라는 공통점을 생각해 냈다. 그렇다면 이제 강아지와 CCTV는 '집을 지킨다'라는 같은 범주
로 묶을 수 있게 되었다.
이러한 예시는 가족 유사성 이론의 핵심인 서로 다른 외형과 본질을 지녔더라도 특정 역할이나 기능을 공유하여 하나의 그룹으로 묶일 수 있다는 개념을 잘 보여준다.
프로토타입 기반 객체지향 프로그래밍에서의 활용
이와 같은 방식은 프로토타입 기반 객체지향 프로그래밍에서 객체들이 특정 상위 개념에 엄격하게 종속되지 않으면서도 유사성을 기반으로 그룹화할 수 있는 장점과 연결된다. 각 객체가 동일한 상위 클래스를 통해 생성되지 않았더라도, 일부 공통된 메서드나 속성을 프로토타입을 통해 공유함으로써 가족(그룹)으로 묶일 수 있다.
이를 통해 코드 중복을 줄이고 재사용성을 높이며 확장 가능성을 확보할 수 있게 한다. 다양한 객체들이 하나의 공통 프로토타입을 사용하여 유사성을 공유하면서도 각자의 독립적인 속성을 유지할 수 있어, 객체가 특정 상황이나 맥락에 따라 새로운 의미나 역할을 유연하게 취할 수 있다.
이로써 가족 유사성 이론은 객체지향 프로그래밍에서 객체의 유연한 그룹화와 공통 기능의 공유 가능성을 설명하는 좋은 예가 된다는 것을 알 수 있다.
두 이론을 살펴보면, 공통적으로 유연하고 동적인 부분이 강조되는 것을 알 수 있다. 따라서 유연하고 동적인 부분이 자바스크립트가 프로토타입 기반을 선택한 이유라고 추측할 수 있지만, 여전히 '왜 유연하고 동적이어야 하는지'에 대한 궁금증이 남게 된다.
답을 찾기 위해서는 자바스크립트가 탄생한 이유를 생각해 볼 필요가 있다.
왜 자바스크립트는 프로토타입 기반 객체지향을 선택했나
앞서 클래스 기반의 코드와 다르게 변경/추가 등의 작업이 유연하게 동적으로 작용하고 있다. 이 유연함은 큰 장점이지만, 동시에 예측하기 어려운 불안정한 구조라고 볼 수도 있다. 왜 안정적인 클래스 기반 객체지향을 따라가지 않고 유연하지만 자칫 불안할 수도 있는 프로토타입 기반 객체지향 구조를 선택했을까?
자바스크립트의 탄생은 정적인 웹페이지에서 생동감을 붙여넣기 위해서였다. 즉, 자바스크립트는 브라우저에서만 쓸 목적으로 고안된 언어로 시작된 언어였다.
따라서 자바스크립트는 유연성과 동적 특성을 중요시한 브라우저 환경에서 상호작용을 빠르게 처리하고 변화에 즉각적으로 대응해야 했고, 이 때문에 가장 적합한 프로토타입을 선택하게 된 것이다. 이 선택 덕분에 자바스크립트는 사용자와의 실시간 상호작용을 원활하게 지원하며, 현대 웹의 핵심 요소로 자리 잡게 되었다.
비록 프로토타입 기반의 유연성이 예측하기 어려운 상속 관계를 초래할 수 있는 단점도 있지만, 이러한 동적 특성 덕분에 브라우저와 서버 환경 모두에서 확장성과 실시간성을 가진 언어로 발전할 수 있었다.
다음 편에서는 프로토타입의 코드, 내부 동작을 살펴보고 프로토타입과 실행 컨텍스트, 렉시컬 스코프, 호이스팅, this와의 관계를 살펴보자.
2편(完)
👉잘못된 내용이 있다면 언제든 피드백 환영입니다~ 🙇🏻♂️
Reference
모던 자바스크립트 Deep Dive, 코어 자바스크립트