Chapter1. 객체지향
객체 지향 프로그래밍
절차 지향 프로그래밍과는 다르게 데이터와 기능을 한곳에 묶어서 처리한다.
속성과 메서드가 하나의 "객체"라는 개념에 포함되며, 이는 자바스크립트 내장 타입인 object(이하, object literal)와는 다르게, 클래스(Class)라는 이름으로 부른다.
📌 클래스와 인스턴스
클래스
- 하나의 모델이 되는 청사진(blueprint)
- 속성, 메소드의 정의
인스턴스
- 청사진을 바탕으로 한 객체(object)
- 각각의 인스턴스는 클래스의 고유한 속성과 메소드를 가짐
new 키워드
- new키워드를 통해 클래스의 인스턴스를 만들 수 있음
- new 키워드가 실행되면 생성자 함수가 실행되며 변수에 클래스의 설계를 가진 인스턴스가 할당됨
생성자 함수
- 인스턴스 객체를 생성하고 초기화하는 메서드다.
- 즉시 생성자 함수가 실행되고 변수에 클래스의 설계를 가진 새로운 객체(=인스턴스)가 할당됨
- 생성자 함수를 작성하지 않으면 기본 생성자default constructor)가 제공됨
- return 값을 만들지 않음
ES5 클래스 작성 문법
function Car(brnad, name, color){
this.brand = brand;
this.name = name;
this.color = color;
}
- prototype 키워드를 사용해야 메서드 정의가 가능
ex) Car.prototype.refuel
ES6 클래스 작성 문법
class Car {
constructor(brand, name, color) {
this.brnad = brand;
this.name = name;
this.color = color;
}
}
- 생성자 함수와 함께 class 키워드 안쪽에 묶어서 정의
this 키워드
- 인스턴스 객체를 의미
- parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성 시 지정하는 값이며 위와 같이 this에 할당한다는 건 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 뜻
📌 객체 지향 프로그래밍
객체 지향 프로그래밍(OPP)
- 사람이 세계를 보고 이해하는 것과 흡사
- 절차 지향 프로그래밍과 달리 데이터와 기능을 한 곳에 묶어 처리한다.
- OOP의 모든 것은 객체로 그룹화 된다.
- 속성과 메서드는 “객체"개념에 포함된다.
- 하나의 모델이 되는 청사진을 만들고 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴을 가진다. (new 키워드를 써서 만든다.)
캡슐화
“코드가 복잡하지 않게 만들고 재사용성을 높임”
- 데이터와 기능을 하나의 단위로 묶는 것 = 데이터(속성)와 기능(메서드)들이 느슨하게 결합되는 것
- 은닉(hiding): 내부 데이터, 내부 구현은 숨기고, 객체 외부에서 필요한 동작(메서드)만 노출시킴
- 느슨한 결합(Loose Coupling)에 유리: 언제든 구현을 수정할 수 있음
추상화
“코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화 시킴”
- 내부 구현은 복잡하지만 실제 노출되는 부분은 단순하게 만든다는 개념
- 추상화를 통해 인터페이스는 단순해짐.
- 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고 단순한 이름으로 정의하는 것에 포커스가 맞춰짐
- 캡슐화가 코드나 데이터의 은닉에 포커스가 맞춰져있다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 포커스가 맞춰져 있다.
상속
“불필요한 코드를 줄여 재사용성 높임”
- 부모 클래스의 특징을 자식 클래스가 물려받는 것
- 기본 클래스의 특징을 파생 클래스가 상속받는다
다형성 Polymorphism
“다형성으로 동일한 메서드에 대해 객체의 특성에 맞게 달리 작성하는 게 가능해짐”
- 똑같은 메서드라고 해도 다른 방식으로 구현될 수 있음
Chapter2. 프로토타입
자바스크립트는 프로토타입 기반 언어다.
클래스 기반 언어에서는 상속을 사용하지만,
프로토타입 기반 언어에선 어떤 객체를 원형으로 삼고 이를 복제(참조)함으로써 상속과 비슷한 효과를 얻는다.
📌 프로토타입과 클래스
클래스 Human과 인스턴스 steve, 프로토타입의 관계
프로토타입
모든 객체들이 메소드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다.
- 프로토타입은 객체다.
- 프로토타입 객체 내부에는 인스턴스가 사용할 메서드를 저장함
- 그러면 인스턴스에서도 숨겨진 프로퍼티인
__proto__
객체를 통해 이 메서드에 접근가능하게 됨
.prototype
- 프로토타입 체인 종착점
- 모든 Built-in 객체들의 원형 객체
- Built-in 객체들의 다양한 공통 특성들을 한 데 가짐
.prototype
과 연결된 객체마다 필요에 의해 기능들을 상속받고 확장해 나감. 이 과정에서 공통된 특성들은 하나의 프로토타입 객체에 모아 그것을 참조하게 하여 메모리 자원을 효율적으로 사용할 수 있음
.__proto__
- 프로토타입을 참조하는 객체.
- 모든 객체는
__proto__
를 통해 자신의 프로토타입에 접근할 수 있다.
- 생략 가능한 프로퍼티
클래스, 인스턴스, 프로토타입의 관계
- 어떤 생성자 함수
constructor
를 new연산자와 함께 호출하면,
constructor
에서 정의된 내용을 바탕으로 새로운 인스턴스가 생성됨
- 이때 instance에는
__proto__
라는 프로퍼티가 자동으로 부여되고
- 이 프로퍼티는
constructor
의 prototype
라는 프로퍼티를 참조함.
📌 프로토타입 체인
객체 지향 프로그래밍 특성 중 상속을 JavaScript에서 구현할 때 프로토타입 체인을 사용
let kimcoding = new Human('김코딩', 30);
kimcoding.age;
kimcoding.gender;
kimcoding.eat();
kimcoding.sleep();
[코드] 클래스 Human의 속성과 메서드 예시
클래스 Student는 Human의 기본적인 메서드를 상속받는다. 다만, 학생은 일반적인 사람의 특징에 추가적인 특징이 필요하다.
let parkhacker = new Student('박해커', 22);
parkhacker.grade;
parkhacker.learn();
[코드] 클래스 Student의 속성과 메서드 예시
프로토타입 체인
- 자바스크립트는 특정 객체의 프로퍼티나 메소드에 접근시 객체 자신의 것뿐 아니라 proto가 가리키는 링크를 따라서 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 접근할 수 있다.
- 즉, 특정 객체의 프로퍼티나 메소드 접근시 만약 현재 객체의 해당 프로퍼티가 존재하지 않는다면 proto가 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례로 검색하는 것이 바로 프로토타입 체인이다.
- 모든 프로토타입 체이닝의 종점은 Object.prototype이다.
- 해당 객체에 없는 프로퍼티나 메소드를 접근할 때 프로토타입 체이닝이 일어난다.
.prototype
- 함수에 정의된 프로퍼티. 기본 세팅은 프로토타입 객체(Prototype Object)를 참조한다. 함수를 정의하면 파싱되는 시점에 프로토타입 객체와 함께 만들어진다.
Prototype Object
: 함수가 만들어지면 함께 만들어지는 객체. 해당 함수의 표본(사전적 의미의 프로토타입) 또는 원형
[[Prototype]]
: 자바스크립트 객체는 [[Prototype]]이라는 내부 프로퍼티가 있고 다른 객체를 참조하는 단순 레퍼런스로 사용한다. 프로토타입 링크라고 부르기도 한다. .__proto__
와 동일한것처럼 말하는 경우도 있는데 엄밀히는 그렇지 않다.
- 모든 함수는
.prototype
프로퍼티를 가지고 있고 .prototype
프로퍼티는 함수의 표본(Prototype Object
)을 참조한다.
.__proto__
- 를 이용하면 부모 클래스의 프로토타입을 탐색할 수 있다.(=상속관계 확인 가능)
- 브라우저에서 [[Prototype]]을 들여다볼 수 있도록 제공하는 기능.
- ES5까지는 비표준이다. 객체에 실제하는 프로퍼티는 아니다. 그리고 프로퍼티처럼 보이지만 실은 게터/세터에 가깝다. 던더 프로토(dunder proto)라고 불리기도 한다.
Object
- 다양한 키 모음 및 더 복잡한 엔티티들을 저장하는 데 사용
- 거의 모든 객체는 Object의 인스턴스다.
- 일반적인 객체는 Object.prototype에서 속성(메서드 포함)을 상속하지만, 이러한 속성들을 가려질 수 있음. 그러나 object는 의도적으로 가려지지 않게 생성되거나 더이상 가려지지 않게 변경될 수 있다.
- 모든 프로토타입 체이닝의 종점은 Object.prototype이다.