You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/01-prototype-inheritance/article.md
+22-21Lines changed: 22 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,7 @@
18
18
19
19
아래 예시처럼 특별한 이름인 `__proto__`을 사용하면 값을 설정할 수 있습니다.
20
20
21
-
```js run
21
+
```js
22
22
let animal = {
23
23
eats:true
24
24
};
@@ -44,7 +44,7 @@ rabbit.__proto__ = animal;
44
44
45
45
예시:
46
46
47
-
```js
47
+
```js run
48
48
let animal = {
49
49
eats: true
50
50
};
@@ -65,7 +65,7 @@ alert( rabbit.jumps ); // true
65
65
66
66
`(*)`로 표시한 줄에선 `animal`이 `rabbit`의 프로토타입이 되도록 설정하였습니다.
67
67
68
-
`(**)`로 표시한 줄에서 `alert` 함수가 `rabbit.eats` 프로퍼티를 읽으려 했는데, `rabbit`엔 `eats`라는 프로퍼티가 없습니다. 이때 자바스크립트는 `[[Prototype]]`이 참조하고 있는 객체인 `animal`에서 `eats`를 얻어냅니다. 아래 그림을 밑에서부터 위로 살펴보세요.
68
+
`(**)`로 표시한 줄에서 `alert` 함수가 `rabbit.eats` 프로퍼티를 읽으려 했는데, `rabbit`엔 `eats`라는 프로퍼티가 없습니다. 이때 자바스크립트는 `[[Prototype]]`이 참조하고 있는 객체인 `animal`에서 `eats`를 얻어냅니다. 다음 그림을 밑에서부터 위로 살펴보세요.
1. 순환 참조(circular reference)는 허용되지 않습니다. `__proto__`를 이용해 닫힌 형태로 다른 객체를 참조하면 에러가 발생합니다.
137
137
2.`__proto__`의 값은 객체나 `null`만 가능합니다. 다른 자료형은 무시됩니다.
138
138
139
-
여기에 더하여 객체엔 오직 하나의 `[[Portotype]]`만 있을 수 있다는 당연한 제약도 있습니다. 객체는 두 개의 객체를 상속받지 못합니다.
139
+
여기에 더하여 객체엔 오직 하나의 `[[Prototype]]`만 있을 수 있다는 당연한 제약도 있습니다. 객체는 두 개의 객체를 상속받지 못합니다.
140
140
141
-
## 쓸 때는 프로토타입을 사용하지 않습니다.
141
+
## 프로토타입은 읽기 전용이다
142
142
143
143
프로토타입은 프로퍼티를 읽을 때만 사용합니다.
144
144
@@ -167,13 +167,13 @@ rabbit.walk = function() {
167
167
rabbit.walk(); // 토끼가 깡충깡충 뜁니다.
168
168
```
169
169
170
-
`rabbit.walk()`를 호출하면 프로토타입에 있는 메서드가 실행되지 않고, 객체 `rabbit`에 추가한 메서드가 실행됩니다.
170
+
`rabbit.walk()`를 호출하면 프로토타입에 있는 메서드가 실행되지 않고, 객체 `rabbit`에 직접 추가한 메서드가 실행됩니다.
171
171
172
172

173
173
174
-
그런데 접근자 프로퍼티(accessor property)는 setter 함수를 통해서 프로퍼티에 값을 할당하므로 이 규칙이 적용되지 않습니다. 접근자 프로퍼티에 값을 할당하는 것은 함수를 호출하는 것과 같기 때문입니다.
174
+
그런데 접근자 프로퍼티(accessor property)는 setter 함수를 사용해 프로퍼티에 값을 할당하므로 접근자 프로퍼티에 값을 할당(`(**)`)하면 객체(`admin`)에 프로퍼티(`fullName`)가 추가되는게 아니라 setter 함수가 호출되면서 위 예시와는 조금 다르게 동작합니다.
175
175
176
-
아래 예시에서 `admin.fullName`이 의도한 대로 잘 작동하는 것을 확인할 수 있습니다.
176
+
아래 예시에서 `admin.fullName`이 의도한 대로 잘 작동하는지 확인해 봅시다.
177
177
178
178
```js run
179
179
let user = {
@@ -199,27 +199,28 @@ alert(admin.fullName); // John Smith (*)
199
199
// setter 함수가 실행됩니다!
200
200
admin.fullName="Alice Cooper"; // (**)
201
201
202
-
alert(admin.fullName); // Alice Cooper , state of admin modified
203
-
alert(user.fullName); // John Smith , state of user protected
202
+
alert(admin.fullName); // Alice Cooper, setter에 의해 추가된 admin의 프로퍼티(name, surname)에서 값을 가져옴
203
+
alert(user.fullName); // John Smith, 본래 user에 있었던 프로퍼티 값
프로토타입 `user`엔 getter 함수 `get fullName`이 있기 때문에 `(*)`로 표시한 줄에선 `get fullName`이 호출되었습니다. 마찬가지로 프로토타입에 이미 setter 함수(`set fullName`)가 정의되어 있기 때문에 `(**)`로 표시한 줄의 할당 연산이 실행되면 객체 `user`에 프로퍼티가 추가되는게 아니라 프로토타입에 있는 setter 함수가 호출됩니다.
207
+
207
208
208
-
## 'this'가 나타내는 것
209
+
## this가 나타내는 것
209
210
210
211
위 예시를 보면 "`set fullName(value)` 본문의 `this`엔 어떤 값이 들어가지?"라는 의문을 가질 수 있습니다. "프로퍼티 `this.name`과 `this.surname`에 값을 쓰면 그 값이 `user`에 저장될까, 아니면 `admin`에 저장될까?"라는 의문도 생길 수 있죠.
211
212
212
213
답은 간단합니다. `this`는 프로토타입에 영향을 받지 않습니다.
213
214
214
-
**메서드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 `this`는 언제나 `.` 앞에 있는 객체가 됩니다.**
215
+
**메서드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 `this`는 언제나 `.` 앞에 있는 객체입니다.**
215
216
216
217
`admin.fullName=`으로 setter 함수를 호출할 때, `this`는 `user`가 아닌 `admin`이 되죠.
217
218
218
219
객체 하나를 만들고 여기에 메서드를 많이 구현해 놓은 다음, 여러 객체에서 이 커다란 객체를 상속받게 하는 경우가 많기 때문에 이런 특징을 잘 알아두셔야 합니다. 상속받은 메서드를 사용하더라도 객체는 프로토타입이 아닌 자신의 상태를 수정합니다.
219
220
220
221
예시를 통해 좀 더 알아봅시다. '메서드 저장소' 역할을 하는 객체 `animal`을 `rabbit`이 상속받게 해보겠습니다.
`rabbit` 말고도 `bird`, `snake` 등이 `animal`을 상속받는다고 해봅시다. 이 객체들도 `rabbit`처럼 `animal`에 구현된 메서드를 사용할 수 있겠죠. 이때 상속받은 메서드의 `this`는 `animal`이 아닌 실제 메서드가 호출되는 시점의 점(`.`) 앞에 있는 객체가 됩니다. 따라서 `this`에 데이터를 쓰면 `animal`이 아닌 해당 객체의 상태가 변화합니다.
254
+
`rabbit` 말고도 `bird`, `snake` 등이 `animal`을 상속받는다고 해봅시다. 이 객체들도 `rabbit`처럼 `animal`에 구현된 메서드를 사용할 수 있습니다. 이때 상속받은 메서드의 `this`는 `animal`이 아닌 실제 메서드가 호출되는 시점의 점(`.`) 앞에 있는 객체가 됩니다. 따라서 `this`에 데이터를 쓰면 `animal`이 아닌 해당 객체의 상태가 변화합니다.
254
255
255
-
메서드는 공유되지만, 객체의 상태는 공유되지 않는다고 결론 내릴 수 있습니다.
256
+
이를 통해 우리는 메서드는 공유되지만, 객체의 상태는 공유되지 않는다고 결론 내릴 수 있습니다.
[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty)를 이용하면 상속 프로퍼티를 순회 대상에서 제외할 수 있습니다. 이 내장 메서드는 `key`에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 `obj`에 직접 구현되어있는 프로퍼티일 때`true`를 반환합니다.
285
+
[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty)를 이용하면 상속 프로퍼티를 순회 대상에서 제외할 수 있습니다. 이 내장 메서드는 `key`에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 `obj`에 직접 구현되어있는 프로퍼티일 때만`true`를 반환합니다.
285
286
286
287
`obj.hasOwnProperty(key)`를 응용하면 아래 예시에서처럼 상속 프로퍼티를 걸러낼 수 있고, 상속 프로퍼티만을 대상으로 무언가를 할 수도 있습니다.
287
288
@@ -306,7 +307,7 @@ for(let prop in rabbit) {
306
307
}
307
308
```
308
309
309
-
위 예시의 상속 관계를 그림으로 나타내면 다음과 같습니다. `rabbit`은 `animal`을, `animal`은 `Object.prototype`을, `Object.prototype`은 `null`을 상속받고 있습니다. `animal`이 `Object.prototype`를 상속받는 이유는 객체 리터럴 방식으로 선언하였기 때문입니다.
310
+
위 예시의 상속 관계를 그림으로 나타내면 다음과 같습니다. `rabbit`은 `animal`을, `animal`은 `Object.prototype`을, `Object.prototype`은 `null`을 상속받고 있습니다. 참고로 `animal`이 `Object.prototype`를 상속받는 이유는`animal`을 객체 리터럴 방식으로 선언하였기 때문입니다.
310
311
311
312

312
313
@@ -327,7 +328,7 @@ for(let prop in rabbit) {
327
328
- 자바스크립트의 모든 객체엔 숨김 프로퍼티 `[[Prototype]]`이 있는데, 이 프로퍼티는 객체나 `null`을 가리킵니다.
328
329
-`obj.__proto__`를 사용하면 프로토타입에 접근할 수 있습니다. `__proto__`는 `[[Prototype]]`의 getter·setter로 쓰이는데, 요즘엔 잘 쓰지 않습니다. 자세한 사항은 뒤쪽 챕터에서 다룰 예정입니다.
329
330
-`[[Prototype]]`이 참조하는 객체를 '프로토타입'이라고 합니다.
330
-
-`obj`에서 프로퍼티를 읽거나 메서드를 호출하려는데 해당하는 프로퍼티나 메서드가 없으면 자바스크립트는 프로토타입에서 프로퍼티나 메서드를 찾습니다.
331
+
-객체에서 프로퍼티를 읽거나 메서드를 호출하려는데 해당하는 프로퍼티나 메서드가 없으면 자바스크립트는 프로토타입에서 프로퍼티나 메서드를 찾습니다.
331
332
- 접근자 프로퍼티가 아닌 데이터 프로퍼티를 다루고 있다면, 쓰기나 지우기와 관련 연산은 프로토타입을 통하지 않고 객체에 직접 적용됩니다.
332
333
- 프로토타입에서 상속받은 `method`라도 `obj.method()`를 호출하면 `method` 안의 `this`는 호출 대상 객체인 `obj`를 가리킵니다.
333
-
-`for..in` 반복문은 객체 자체에서 정의한 프로퍼티뿐만 아니라 상속 프로퍼티도 순회 대상에 포함합니다. 반면, 키-값과 관련된 내장 메서드 대부분은 상속 프로퍼티는 제외하고 객체 자체 프로퍼티만을 대상으로 동작합니다.
334
+
-`for..in` 반복문은 객체 자체에서 정의한 프로퍼티뿐만 아니라 상속 프로퍼티도 순회 대상에 포함합니다. 반면, 키-값과 관련된 내장 메서드 대부분은 상속 프로퍼티는 제외하고 객체 자체 프로퍼티만을 대상으로 동작합니다.
0 commit comments