Skip to content

Commit 21ffe6a

Browse files
authored
chapter 17 업로드 (ahnlab-220#5)
* feat: chapter_06, chapter_07 업로드 * feat: _toc.yml에 chapter_06, chapter_07 섹션 추가 * feat: _toc.yml 파일에 챕터, 섹션 추가 * feat: chapter_17 업로드
1 parent 56d9a05 commit 21ffe6a

2 files changed

Lines changed: 119 additions & 0 deletions

File tree

book/_toc.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ parts:
1111
- file: docs/chapter_05
1212
- file: docs/chapter_06
1313
- file: docs/chapter_07
14+
- file: docs/chapter_08
15+
- file: docs/chapter_09
16+
- file: docs/chapter_10
17+
- file: docs/chapter_11
18+
- file: docs/chapter_12
19+
- file: docs/chapter_13
20+
- file: docs/chapter_14
21+
- file: docs/chapter_15
22+
- file: docs/chapter_16
23+
- file: docs/chapter_17
1424
- caption: 개인 공간
1525
chapters:
1626
- file: 공희재/main
@@ -19,6 +29,14 @@ parts:
1929
- file: 공희재/chapter_05
2030
- file: 공희재/chapter_06
2131
- file: 공희재/chapter_07
32+
- file: 공희재/chapter_08
33+
- file: 공희재/chapter_09
34+
- file: 공희재/chapter_10
35+
- file: 공희재/chapter_11
36+
- file: 공희재/chapter_12
37+
- file: 공희재/chapter_14
38+
- file: 공희재/chapter_15
39+
- file: 공희재/chapter_17
2240
- file: 김현우/main
2341
sections:
2442
- file: 김현우/chapter_04

book/docs/chapter_17.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Chapter 17 - 생성자 함수에 의한 객체 생성
2+
3+
이번 장에서는 다양한 객체 생성 방식 중에서 **Constructor(생성자 함수)를 사용해 객체를 생성하는 방식**을 살펴보자.
4+
5+
## 1. Object 생성자 함수
6+
다음과 같이 `new` 연산자와 함께 `Object` 생성자 함수를 호출하면 빈 객체를 생성해 반환할 수 있다.<br/>
7+
빈 객체를 생성 후 프로퍼티 또는 메서드를 추가해 객체를 완성하면 된다.
8+
9+
![image](https://github.com/user-attachments/assets/dd61cb9b-b2e0-41a8-96b5-bfc121b48ea1)
10+
11+
**용어 정리:**
12+
* Constructor(생성자 함수): `new` 연산자와 함께 호출해 객체(인스턴스)를 생성하는 함수를 말한다.
13+
* Instance(인스턴스): Constructor에 의해 생성된 객체를 말한다.
14+
15+
그러나! Object 생성자 함수를 사용해 객체를 생성하는 방식은,<br/>
16+
특별한 이유가 없다면 그다지 유용하진 않다. (그냥 객체 리터럴을 쓰는 게 낫다.)
17+
18+
그럼 이제 생성자 함수를 배워보자.
19+
20+
21+
## 2. Constructor: 생성자 함수
22+
### 2-1. 객체 리터럴로 객체를 만들 때 문제점
23+
객체 리터럴로 객체를 생성하는 방식은 직관적이고 간편하다는 장점이 있지만,<br/>
24+
동일한 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우에는 비효율적이라는 단점이 있다.
25+
26+
### 2-2. 생성자 함수로 객체를 만들 때 문제점
27+
그에 비해 생성자 함수로 객체를 생성하는 방식은, 마치 다른 언어의 클래스처럼<br/>
28+
프로퍼티 구조가 동일한 객체 여러 개를 아래처럼 간편하게 생성할 수 있다.
29+
30+
![{1016F6F5-0E1E-4595-A20C-F9C88F2345D7}](https://github.com/user-attachments/assets/248d26a5-531f-428b-9c35-6a22b282d4ef)
31+
32+
이처럼 생성자 함수는 객체(인스턴스)를 생성하는 함수다.<br/>
33+
**하지만!** 다른 클래스 기반 언어의 생성자와는 달리, 자바스크립트의 생성자 함수는 **형식이 정해져 있지 않다**.<br/>
34+
**일반 함수**와 동일한 방법으로 생성자 함수를 정의하고 **`new` 연산자와 함께 호출하면 그 함수는 생성자 함수**가 된다.
35+
36+
### 2-3. 생성자 함수의 인스턴스 생성 과정
37+
생성자 함수의 역할은 1. **인스턴스를 생성하는 것**과<br/>
38+
2. 생성한 인스턴스의 프로퍼티를 추가하고, 초기값을 할당하는 **초기화를 하는 것**이다.<br/>
39+
자바스크립트 엔진은 `new` 연산자와 함께 생성자 함수를 호출하면,<br/>
40+
다음과 같이 세 단계에 걸쳐 암묵적으로 인스턴스를 생성, 초기화, 그리고 반환한다.
41+
42+
![{31654410-9A7A-4418-9BD8-1661F8E4BBB5}](https://github.com/user-attachments/assets/90354fbc-7691-4679-9f13-8bd54ecfc040)
43+
44+
위 예제를 차례대로 살펴보자.
45+
46+
#### 1) 인스턴스 생성과 `this` 바인딩
47+
`new` 연산자와 함께 생성자 함수를 호출하면 자바스크립트 엔진은 **암묵적으로 빈 객체를 생성**하고,<br/>
48+
이 객체(인스턴스)를 **`this`에 바인딩**한다. 이 과정은 함수 몸체의 코드를 한 줄씩 실행하는 **런타임 이전에 처리**된다.
49+
#### 2) 인스턴스 초기화
50+
`this`에 바인딩한 인스턴스를 초기화한다. 이 처리는 개발자가 기술한다.
51+
#### 3) 인스턴스 반환
52+
초기화를 끝낸 인스턴스를 바인딩한, `this`를 암묵적으로 반환한다.<br/>
53+
**그러나!** 다음과 같은 예외가 있다:
54+
* 만약 `this`가 아닌 다른 객체를 명시적으로 반환하면, `this`가 아닌 return 문에 명시한 그 객체를 반환한다.
55+
* 만약 `this`가 아닌 어떤 원시 값을 명시적으로 반환하면, 원시 값 반환은 무시하고 암묵적으로 `this`를 반환한다.
56+
57+
**따라서, 이렇게 생성자 함수의 기본 동작을 훼손하지 않으려면, 생성자 함수 내부에서 return 문을 반드시 생략해야 한다.**
58+
59+
### 2-4. 내부 메서드 [[Call]][[Construct]]
60+
함수는 객체이므로 **ordinary object(일반 객체)가 지닌 내부 슬롯과 내부 메서드를 똑같이** 지닌다.<br/>
61+
뿐만 아니라, 함수로서 동작하기 위해 **함수 객체만을 위한 내부 슬롯과 내부 메소드**도 추가로 가지고 있다.
62+
63+
그 중 이번 절에서 살펴볼 내부 메서드는 [[**Call**]][[**Construct**]]이다.<br/>
64+
[[Call]]은 함수가 **일반 함수로서** 호출될 때 쓰이는 내부 메서드이고,<br/>
65+
[[Construct]]`new` 연산자와 함께 **생성자 함수로서** 호출될 때 쓰이는 내부 메서드이다.
66+
67+
[[Call]]을 갖는 함수 객체를 우리는 **callable**이라고 부르고,<br/>
68+
[[Construct]]를 갖는 함수 객체를 우리는 **constructor**라고 부른다. (갖지 않는 함수 객체는 **non-constructor**라고 부른다.)
69+
70+
중요한 사실은, 모든 함수 객체는 호출할 수 있지만, 생성자 함수로서 호출할 수 있지는 않다는 것이다.<br/>
71+
**즉, 함수 객체는 무조건 callable이지만, 경우에 따라 constructor일 수도 있고, non-constructor일 수도 있다.**
72+
73+
그렇다면 어떤 함수 객체가 constructor인지 non-constructor인지 어떻게 구분할까?
74+
75+
76+
### 2-5. constructor와 non-constructor의 구분
77+
자바스크립트 엔진은 다음과 같이 **함수 정의** 방식에 따라 constructor와 non-constructor를 구분한다.
78+
* constructor: 함수 선언문, 함수 표현식, 클래스(클래스도 함수임)
79+
* non-constructor: ECMAScript 사양에서 인정하는 메서드(=ES6 메서드 축약 표현), 화살표 함수
80+
81+
82+
### 2-6. `new` 연산자
83+
`new` 연산자와 함께 함수를 호출하면, 그 함수는 이제 생성자 함수가 된다.<br/>
84+
다시 말해, 내부 메서드 [[Call]]이 호출되는 것이 아니라, 이제 [[Construct]]가 호출되는 것이다.
85+
86+
반대로, `new` 연산자 없이 생성자 함수를 호출하면 그 함수는 일반 함수다.<br/>
87+
다시 말해, 내부 메서드 [[Construct]]이 호출되는 것이 아니라, 이제 [[Call]]가 호출되는 것이다.
88+
89+
생성자 함수로서 호출되는지, 일반 함수로서 호출되는지에 따라 함수 내부의 `this`가 바인딩되는 대상이 달라진다.<br/>
90+
`new` 연산자와 함께 생성자 함수로서 호출하면 `this`는 생성자 함수가 만든 인스턴스를 가리키고,<br/>
91+
일반 함수로서 호출하면 `this`는 전역 객체 `window`를 가리키게 된다.
92+
93+
생성자 함수와 일반 생성자 함수는 형식적 차이가 없으므로,<br/>
94+
**생성자 함수의 이름**을 지을 땐 일반적으로 **PascalCase**로 명명해 일반 함수와 구분해야 한다.
95+
96+
97+
### 2-7. `new.target`
98+
앞서 이야기한 PascalCase를 쓴다고 하더라도 위험성이 여전히 존재하므로,<br/>
99+
ES6부터는 함수 내부에서 본인이 생성자 함수로서 호출되었는지 확인하게 해주는 new.target라는 메타 프로퍼티를 지원한다.
100+
101+
끝.

0 commit comments

Comments
 (0)