IM 코스를 시작하고 첫 주가 지났다. 오늘이 이번 주를 통틀어서 가장 또렷한 정신이었던 것 같다. 앞으로도 오늘만 같았으면 좋겠다!
오늘은 배운 내용을 가지고 여러가지를 만들어보면서 노는데 시간을 많이 들였다. 재밌었다😎
__proto__
, constructor, prototypeclass
키워드, super
키워드OOP는 Object Oriented Programming의 약자다. 한국어로는 "객체지향 프로그래밍"이다.
객체지향 프로그래밍(OOP)에서는 기능들을 묶어 하나의 객체로 만든다. 그런 식으로 프로그램을 여러개의 “객체”로 나누고, 각 객체의 메소드나 필드를 호출하면서 서로간의 상호작용을 통해 알고리즘을 구성하는 방식을 객체지향 프로그래밍이라고 한다.
개발을 하다 보면 어떤 기능을 가져와 그것을 확장해서 사용하고 싶을 때가 있다.
예를 들어, 어떤 웹페이지의 사용자에 관한 프로퍼티와 메서드를 가진 user
라는 객체가 있다. 이때 웹페이지의 사용자는 관리자(admin)와 일반 유저(guest)로, 여기서 일반 유저는 다시 판매자(seller), 구매자(buyer)로 나뉘게 될 것이다. admin
과 guest
객체는 user
와 약간의 차이가 있을 뿐 상당히 유사하다.
이 때, 자바스크립트 언어의 고유 기능인 프로토타입 상속(prototypal inheritance)을 이용하면 user
의 메서드를 복사하거나 다시 구현하지 않고 user
에 약간의 기능을 얹어 admin
과 guest
객체를 만들 수 있다.
어떤 객체가 가지고 있는 숨김 프로퍼티인
[[Prototype]]
값이 다른 객체를 참조하는 경우, 그 참조 대상을 프로토타입(prototype)이라고 한다.
자바스크립트의 객체는 명세서에서 명명한 [[Prototype]]
이라는 hidden property를 갖는다. 이 히든 프로퍼티 값은 null
이거나 다른 객체에 대한 참조
가 되는데, 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다.
자바스크립트는 프로토타입(Prototype) 기반 언어이다.
자바스크립트에는 "클래스(Class)"라는 개념이 없다. 대신 "프로토타입(Prototype)"이 존재하기 때문에 자바스크립트를 프로토타입 기반 언어라고 부른다.
⚠ ES2015부터class
키워드를 지원하기 시작했으나, 문법적인 양념일 뿐이며 자바스크립트는 여전히 프로토타입 기반의 언어다.
자바스크립트에는 클래스 개념이 없기 때문에 당연히 상속기능(기본base클래스의 특징을 파생derive클래스가 물려받는 것, OOP의 주요 컨셉 중 하나)도 없다.
이를 해결하기 위해 자바스크립트에서는 프로토타입을 기반으로 상속을 흉내내도록 구현해 사용한다.
__proto__
, constructor
, prototype
함수가 생성되면 동시에 해당 함수의 Prototype 객체도 생성된다.
우리는 함수의 prototype 속성을 이용해 해당 함수의 Prototype Object에 접근할 수 있다. (prototype 속성은 오직 함수만 가질 수 있다.)
해당 함수의 Prototype Object에는 기본적으로 constructor
프로퍼티와 __proto__
프로퍼티가 존재한다. 이 때, constructor 프로퍼티의 값은 해당 함수가 된다. __proto__
는 해당 객체를 생성한 함수의 Prototype 객체를 가리킨다.__proto__
는 해당 객체를 생성한 함수의 Prototype 객체를 가리킨다.
객체는 언제나 함수(Function)로 생성된다.
객체는 언제나 함수로 생성되며, 모든 객체가 가지고 있는
constructor
와__proto__
속성은 객체를 생성한 함수에 대한 정보를 담고 있다.
constructor
의 값은 "해당 객체를 생성한 함수"이며,__proto__
의 값은 "해당 객체를 생성한 함수의 프로토타입 객체"이다.
class
키워드 및 super
키워드 이용 방법class
키워드기본 문법
class BaseClass {
// 여러 메서드를 정의할 수 있음
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
이렇게 클래스를 만들고, new BaseClass()를 호출하면 내부에서 정의한 메서드가 들어 있는 객체(인스턴스)가 생성된다.
class
키워드를 사용하면 클래스를 만드는 일이 훨씬 간단해진다.
아래는 class
키워드를 사용하지 않고 클래스를 만든 예제이다.
super
키워드super.method(...)
는 Base Class에 정의된 메소드method
를 호출한다.
super(...)
는 Base Class의 constructor를 호출하는데, 파생 Class의 contructor 내부에서만 사용할 수 있다. 파생 Class의 constructor에서는 반드시 super(...)
를 호출해야 한다.
왜 파생 Class의 constructor에서는 반드시
super(...)
를 호출해야 하나요?자바스크립트는 '파생 클래스의 생성자 함수(derived constructor)'와 그렇지 않은 생성자 함수를 구분한다. (파생 클래스의 생성자 함수에는 특수 내부 프로퍼티인
[[ConstructorKind]]:"derived"
가 붙는다.)
일반 클래스가new
와 함께 실행되면, 빈 객체가 만들어지고 this에 그 객체를 할당해서 인스턴스를 만든다.
반면에 파생 클래스가new
와 함께 실행되면 파생클래스의 생성자 함수는 Base Class의 constructor가 작업을 해주길 기다린다. (자기는 아무것도 안한다.)
class 의 속성(property)들은 기본적으로 public 하며 class 외부에서 읽히고 수정될 수 있다. 하지만, ES2019 에서는 해쉬 # prefix 를 추가해 private class 필드를 선언할 수 있게 되었다.
MDN Private class fields
- constructor 함수에는 적용할 수 없다.