OOP 패러다임 : class-based vs prototype-based
class-based 언어 => 클래스가 먼저 정의되어 있고, 객체는 클래스를 기반으로 인스턴스화 되어 생성된다.
만약 두 객체 "사과", "오렌지"가 과일 클래스의 인스턴스라면 이 둘은 본질적으로 과일이고, 같은 방식으로 핸들링할 수 있음을 보장한다.
(개발자는 color, sugar_content, is_ripe 같은 동일한 attribute를 가지고 있음을 예상할 수 있다)
prototype-based 언어 => 객체가 primary entity 이다. 클래스는 존재하지 않음 (그래도 자바스크립트 es6에 클래스 키워드는 있음. 내부적으로 class-based 언어의 클래스와 완전 동일하게 동작한다고 말할 수는 없지만)
어떤 객체의 프로토타입은 해당 객체가 연결되어 있는 또다른 객체일 뿐이다. 모든 객체는 단 한개의 프로토타입 링크를 가지고 있다 (자바스크립트 __proto__ )
새로운 객체는 이미 존재하는 객체(와 그것의 프로토타입) 기반으로 생성될 수 있다.
만약 fruit이라는 객체가 존재하는데 2개의 서로 다른 객체 orange, apple이 prototype으로 fruit을 참조하고 있다면, orange 와 apple 역시 fruit이라고 부를 수 있음(프로토타입 체이닝으로 orange나 apple에 없는 attribute은 fruit에서 찾음)
fruit 클래스 개념이 명시적으로 존재하지 않지만, 객체가 equivalenece class(=set)로서 같은 prototype을 공유한다.
프로토타입의 모든 attribute와 메소드는 이 프로토타입으로 정의된 equivalence class 안의 모든 객체들에게도 전이된다.
같은 equivalence class에 속하더라도 개인적으로 갖고 있는 attribute나 method는 공유되지 않음.
프로토타입을 통해서 single inheritance만 구현할 수 있음 (객체마다 오직 하나의 __proto__ 참조 값만 가지므로 다중 상속 구현 불가)
*equivalence class
In mathematics, when the elements of some set S have a notion of equivalence defined on them, then one may naturally split the set S into equivalence classes.
🦄stack overflow 질문 : prototype based vs class based inheritance
질문 : 왜 자바스크립트는 prototype-based 객체 지향 방식을 채택했을까요? class-based OO와 비교하여 prototype-based OO의 장단점이 무엇이 있을까요?
답변 :
역사적으로 살펴보면 "클래스"의 태동은 Simula나 smalltalk같은 언어에서의 equivalence class(set) 개념의 class로,
같은 state space(possible value) -(> 프로퍼티), operation (-> 메소드) 을 공유하는 객체 집합을 뜻하거나 (simula), 자바스크립트 처럼 런타임에 클래스를 열어서 메소드를 추가할 수 있는 식(smalltalk, 이건 루비도 그런데..!!)이었음.
후의 객체 지향언어에서 static(컴파일타임) 타입 체킹을 하고 싶어서 컴파일 타임에 결정되는 fixed 클래스 개념이 도입되었다.
open-class 버전에서는 더 유연성이 있었다면, 이 새로운 fixed 버전에서는 컴파일 타임에 여러 정적 분석을 할 수 있어짐.
class-based 언어에서 복사는 compile 타임에 이루어진다. prototype-based 언어에서는 operation들이 프로토타입의 자료구조에 저
장되어 있다가 런타임에 copy, modify가 이루어진다.
이제 자바스크립트가 왜 prototype 방식을 선택했는지 말해보자. 런타임에 할 수 있는 간단한, 논리적인, 엘레강트 한 매커니즘이기 때문이다. Javascript/ECMA script를 시작할 때만 해도 훨씬 열악한 브라우저, 컴퓨팅 환경에서 돌아야하는 언어였다. prototype-based 방식을 선택했다는 것은, 심플한 인터프리터로 원하는 기능을 유지할 수 있었다는 거다.
*
대부분의 prototype-based 시스템은 런타임에 prototype 변경을 장려함.
class-based 시스템에서는 아주 소수만 런타임에 클래스 변경하는 것을 허용함 (=> 예) Common Lisp, Dylan, Objective-C, Perl, Python, Ruby, Smalltalk). 이 특성 때문에 루비가 메타프로그래밍이 가능하다고 하는구만..
*
prototype-oriented language
=> Javascript (and other ECMAScript), Lua, Cecil, NewtonScript, lo, loke, Moo, REBOL, AHK
class-based programming language
=> Java, Go, Ruby, C++, C#, Common Lisp, PHP, Python, Simula, Smalltalk
🦄자바스크립트 객체
2021.05.10 - [언어와 프레임워크/javascript] - 생성자 함수 vs 클래스