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
This article covers an advanced topic, to understand certain edge-cases better.
4
+
```warn header="심화 학습"
5
+
이번 절에선 특정 에지 케이스(edge case)를 설명하기 위한 심화 내용을 다룹니다.
6
6
7
-
It's not important. Many experienced developers live fine without knowing it. Read on if you're want to know how things work under the hood.
7
+
숙련된 상당수의 개발자가 이 절에서 다룰 내용을 모른 채로 일하고 있지만 문제가 없고, 중요한 내용은 아니기 때문에 자바스크립트 내부에서 어떤 일이 일어나는지 알고 싶지 않다면 이번 글은 넘어가거나 미뤄도 괜찮습니다.
8
8
```
9
9
10
-
A dynamically evaluated method call can lose `this`.
10
+
복잡한 상황에서 메서드를 호출하면 `this` 값을 잃어버리는 경우가 생깁니다.
11
11
12
-
For instance:
12
+
예시를 살펴봅시다.
13
13
14
14
```js run
15
15
let user = {
@@ -18,42 +18,42 @@ let user = {
18
18
bye() { alert("Bye"); }
19
19
};
20
20
21
-
user.hi(); //works
21
+
user.hi(); //John (간단한 호출은 의도한 대로 잘 동작합니다.)
22
22
23
-
//now let's call user.hi or user.bye depending on the name
23
+
//name에 따라 user.hi나 user.bye가 호출되게 해봅시다.
24
24
*!*
25
-
(user.name=="John"?user.hi:user.bye)(); //Error!
25
+
(user.name=="John"?user.hi:user.bye)(); //TypeError: Cannot read property 'name' of undefined
26
26
*/!*
27
27
```
28
28
29
-
On the last line there is a conditional operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`.
29
+
마지막 줄에서 조건부 연산자를 사용해 `user.hi`나 `user.bye` 중 하나가 호출되도록 했습니다. user의 name이 "John"이므로 `user.hi`가 호출될 것이라 예상하며 말이죠.
30
30
31
-
Then the method is immediately called with parentheses `()`. But it doesn't work correctly!
31
+
그런데 에러가 발생했습니다. 뒤에 `()`가 있어서 메서드 hi가 즉시 호출될 것이라 예상했는데 원하는 대로 되지 않았네요.
32
32
33
-
As you can see, the call results in an error, because the value of `"this"` inside the call becomes `undefined`.
33
+
에러는 메서드를 호출할 때 `"this"`에 `undefined`가 할당되었기 때문에 발생했습니다.
34
34
35
-
This works (object dot method):
35
+
마지막 줄이 아래와 같았다면 에러 없이 잘 작동했을 겁니다.
36
36
```js
37
37
user.hi();
38
38
```
39
39
40
-
This doesn't (evaluated method):
40
+
그런데 아래 코드에선 에러가 발생하죠.
41
41
```js
42
-
(user.name=="John"?user.hi:user.bye)();// Error!
42
+
(user.name=="John"?user.hi:user.bye)();
43
43
```
44
44
45
-
Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works.
45
+
원인이 뭘까요? 원인을 알려면 `obj.method()`를 호출했을 때, 내부에서 어떤 일이 일어나는지 알아야 합니다.
46
46
47
-
## Reference type explained
47
+
## 참조 타입 자세히 알아보기
48
48
49
-
Looking closely, we may notice two operations in `obj.method()` statement:
49
+
코드를 유심히 살펴보면 `obj.method()`엔 연산이 두 개 있다는 걸 눈치챌 수 있습니다.
50
50
51
-
1.First, the dot `'.'` retrieves the property `obj.method`.
52
-
2.Then parentheses `()` execute it.
51
+
1.점 `'.'`은 객체 프로퍼티 `obj.method`에 접근합니다.
52
+
2.괄호 `()`는 접근한 프로퍼티(메서드)를 실행합니다.
53
53
54
-
So, how does the information about `this`get passed from the first part to the second one?
54
+
그렇다면 첫 번째 연산에서 얻은 `this`정보가 어떻게 두 번째 연산으로 전달될까요?
55
55
56
-
If we put these operations on separate lines, then `this`will be lost for sure:
56
+
두 연산을 각각 별도의 줄에서 두었다면 `this`정보를 잃는 건 확실합니다.
57
57
58
58
```js run
59
59
let user = {
@@ -62,53 +62,47 @@ let user = {
62
62
}
63
63
64
64
*!*
65
-
//split getting and calling the method in two lines
65
+
//메서드 접근과 호출을 별도의 줄에서 실행함
66
66
let hi =user.hi;
67
-
hi(); //Error, because this is undefined
67
+
hi(); //this가 undefined이기 때문에 에러가 발생합니다.
68
68
*/!*
69
69
```
70
70
71
-
Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`.
71
+
`hi = user.hi`에선 함수가 변수에 할당됩니다. 그런데 마지막 줄과는 완전히 독립적으로 동작하므로 `this`엔 아무런 값도 저장되지 않습니다.
72
72
73
-
**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).**
73
+
**`user.hi()`를 의도한 대로 동작시키기 위해 자바스크립트는 속임수를 사용합니다. `'.'`이 함수가 아닌, [참조 타입(Reference Type)](https://tc39.github.io/ecma262/#sec-reference-specification-type) 값을 반환하게 하죠.**
74
74
75
-
The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language.
75
+
참조 타입은 '명세서 에서만 사용되는 타입(specification type)'입니다. 개발자가 실제론 사용할 수 없습니다.
76
76
77
-
The value of Reference Type is a three-value combination `(base, name, strict)`, where:
77
+
참조 타입에 속하는 값은 `(base, name, strict)`이 조합된 형태를 띱니다.
78
78
79
-
-`base` is the object.
80
-
-`name` is the property name.
81
-
-`strict` is true if `use strict` is in effect.
79
+
-`base`: 객체
80
+
-`name`: 프로퍼티의 이름
81
+
-`strict`: 엄격 모드에서 true
82
82
83
-
The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is:
83
+
`user.hi`로 프로퍼티에 접근하면 함수가 아닌, 참조형(참조 타입) 값을 반환합니다. 엄격 모드에선 아래와 같은 값이 반환되죠.
84
84
85
85
```js
86
-
//Reference Type value
86
+
//참조형 값
87
87
(user, "hi", true)
88
88
```
89
89
90
-
When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this`(`=user` in this case).
90
+
참조형 값에 괄호 `()`를 붙여 호출하면 객체, 객체의 메서드와 연관된 모든 정보를 받습니다. 이 정보를 기반으로 `this`(`=user`)가 결정됩니다.
91
91
92
-
Reference type is a special "intermediary" internal type, with the purpose to pass information from dot `.` to calling parentheses`()`.
92
+
이렇게 참조 타입은 내부에서 점 `.`연산에서 알아낸 정보를 괄호`()`로 전달해주는 '중개인' 역할을 합니다.
93
93
94
-
Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi`(a function) and passes it on. So any further operation "loses"`this`.
94
+
그런데 점 연산 이외의 연산(할당 연산 등)은 참조 타입을 통째로 버리고 `user.hi`값(함수)만 받아 전달합니다. 이 때문에 점 이외의 연산에선`this` 정보가 사라집니다.
95
95
96
-
So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()`or square brackets`obj['method']()`syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind).
96
+
`obj.method()`같이 점을 사용하거나,`obj[method]()`같이 대괄호를 사용해 함수를 호출했을 때만 `this` 값이 의도한 대로 전달됩니다. 이런 문제는 [func.bind()](/bind#solution-2-bind) 등을 이용하면 해결 할 수 있는데, 이에 대해선 추후에 알아보도록 하겠습니다.
97
97
98
-
## Summary
98
+
## 요약
99
99
100
-
Reference Type is an internal type of the language.
100
+
참조 타입은 자바스크립트 내부에서 사용되는 타입입니다.
101
101
102
-
Reading a property, such as with dot `.` in `obj.method()` returns not exactly the property value, but a special "reference type" value that stores both the property value and the object it was taken from.
102
+
`.`이나 대괄호를 사용해 객체 프로퍼티인 메서드(`obj.method()`)에 접근하려 하면 정확한 프로퍼티 값이 반환되는 것이 아니라 특별한 형태의 값인 '참조 타입' 값이 반한됩니다. 이 참조타입 값엔 프로퍼티 값과 프로퍼티가 정의된 객체 정보가 담겨있습니다.
103
103
104
-
That's for the subsequent method call `()` to get the object and set `this` to it.
104
+
`()`를 사용해 메서드를 호출할 때, 메서드 내에서 사용되는 `this`에 제대로 된 객체 정보를 전달해 줄 수 있는 이유가 바로 '참조 타입' 덕분입니다.
105
105
106
-
For all other operations, the reference type automatically becomes the property value (a function in our case).
106
+
그런데 `.`이나 대괄호 이외의 연산에선 참조 타입이 그냥 프로퍼티 값으로 변해버립니다. 객체 메서드라면 함숫값으로 변해버리죠.
107
107
108
-
The whole mechanics is hidden from our eyes. It only matters in subtle cases, such as when a method is obtained dynamically from the object, using an expression.
109
-
110
-
111
-
112
-
113
-
114
-
result of dot `.` isn't actually a method, but a value of `` needs a way to pass the information about `obj`
108
+
이런 내부 동작은 보이지 않는 곳에서 일어납니다. 참조 타입이 어떻게 동작하는지 알아야 해결할 수 있는 문제는 표현식을 이용해 동적으로 객체에서 메서드를 가져올 때와 같이 자주 발생하지 않습니다.
0 commit comments