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
One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference".
3
+
객체와 원시 타입의 근본적인 차이 중 하나는 객체는 '참조에 의해(by reference)' 저장되고 복사된다는 것입니다.
4
4
5
-
Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value".
5
+
원시값(문자열, 숫자, 불린 값)은 '값 그대로' 저장·할당되고 복사되는 반면에 말이죠.
6
6
7
-
For instance:
7
+
예시:
8
8
9
9
```js
10
10
let message ="Hello!";
11
11
let phrase = message;
12
12
```
13
13
14
-
As a result we have two independent variables, each one is storing the string `"Hello!"`.
14
+
예시를 실행하면 두 개의 독립된 변수에 각각 문자열 `"Hello!"`가 저장됩니다.
15
15
16
16

17
17
18
-
Objects are not like that.
18
+
그런데 객체의 동작방식은 이와 다릅니다.
19
19
20
-
**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.**
20
+
**변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장됩니다.**
21
21
22
-
Here's the picture for the object:
22
+
그림을 통해 변수 user에 객체를 할당할 때 무슨 일이 일어나는지 알아봅시다.
23
23
24
24
```js
25
25
let user = {
@@ -29,76 +29,76 @@ let user = {
29
29
30
30

31
31
32
-
Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it.
32
+
객체는 메모리 내 어딘가에 저장되고, 변수 `user`엔 객체를 '참조'할 수 있는 값이 저장됩니다.
33
33
34
-
**When an object variable is copied -- the reference is copied, the object is not duplicated.**
34
+
따라서 **객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체는 복사되지 않습니다.**
35
35
36
-
For instance:
36
+
예시:
37
37
38
38
```js no-beautify
39
39
let user = { name:"John" };
40
40
41
-
let admin = user; //copy the reference
41
+
let admin = user; //참조값을 복사함
42
42
```
43
43
44
-
Now we have two variables, each one with the reference to the same object:
44
+
변수는 두 개이지만 각 변수엔 동일 객체에 대한 참조 값이 저장되죠.
45
45
46
46

47
47
48
-
We can use any variable to access the object and modify its contents:
48
+
따라서 객체에 접근하거나 객체를 조작할 땐 여러 변수를 사용할 수 있습니다.
49
49
50
50
```js run
51
51
let user = { name:'John' };
52
52
53
53
let admin = user;
54
54
55
55
*!*
56
-
admin.name='Pete'; //changed by the "admin" reference
56
+
admin.name='Pete'; //'admin' 참조 값에 의해 변경됨
57
57
*/!*
58
58
59
-
alert(*!*user.name*/!*); //'Pete', changes are seen from the "user" reference
59
+
alert(*!*user.name*/!*); //'Pete'가 출력됨. 'user' 참조 값을 이용해 변경사항을 확인함
60
60
```
61
61
62
-
The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use another key (`user`) we can see changes.
62
+
객체를 서랍장에 비유하면 변수는 서랍장을 열 수 있는 열쇠라고 할 수 있습니다. 서랍장은 하나, 서랍장을 열 수 있는 열쇠는 두 개인데, 그중 하나(`admin`)를 사용해 서랍장을 열어 정돈한 후, 또 다른 열쇠로 서랍장을 열면 정돈된 내용을 볼 수 있습니다.
63
63
64
-
## Comparison by reference
64
+
### 참조에 의한 비교
65
65
66
-
The equality `==` and strict equality `===` operators for objects work exactly the same.
66
+
객체 비교 시 동등 연산자 `==`와 일치 연산자 `===`는 동일하게 동작합니다.
67
67
68
-
**Two objects are equal only if they are the same object.**
68
+
**비교 시 피연산자인 두 객체가 동일한 객체인 경우에 참을 반환하죠.**
69
69
70
-
Here two variables reference the same object, thus they are equal:
70
+
두 변수가 같은 객체를 참조하는 예시를 살펴봅시다. 일치·동등 비교 모두에서 참이 반환됩니다.
71
71
72
72
```js run
73
73
let a = {};
74
-
let b = a; //copy the reference
74
+
let b = a; //참조에 의한 복사
75
75
76
-
alert( a == b ); // true, both variables reference the same object
76
+
alert( a == b ); // true, 두 변수는 같은 객체를 참조합니다.
77
77
alert( a === b ); // true
78
78
```
79
79
80
-
And here two independent objects are not equal, even though both are empty:
80
+
다른 예시를 살펴봅시다. 두 객체 모두 비어있다는 점에서 같아 보이지만, 독립된 객체이기 때문에 일치·동등 비교하면 거짓이 반환됩니다.
81
81
82
82
```js run
83
83
let a = {};
84
-
let b = {}; //two independent objects
84
+
let b = {}; //독립된 두 객체
85
85
86
86
alert( a == b ); // false
87
87
```
88
88
89
-
For comparisons like `obj1 > obj2`or for a comparison against a primitive `obj ==5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons occur very rarely, usually as a result of a coding mistake.
89
+
`obj1 > obj2`같은 대소 비교나 `obj ==5` 같은 원시값과의 비교에선 객체가 원시형으로 변환됩니다. 객체가 어떻게 원시형으로 변하는지에 대해선 곧 학습할 예정인데, 이러한 비교(객체끼리의 대소 비교나 원시값과 객체를 비교하는 것)가 필요한 경우는 매우 드물긴 합니다. 대개 코딩 실수 때문에 이런 비교가 발생합니다.
90
90
91
-
## Cloning and merging, Object.assign
91
+
## 객체 복사, 병합과 Object.assign
92
92
93
-
So, copying an object variable creates one more reference to the same object.
93
+
객체가 할당된 변수를 복사하면 동일한 객체에 대한 참조 값이 하나 더 만들어진다는 걸 배웠습니다.
94
94
95
-
But what if we need to duplicate an object? Create an independent copy, a clone?
95
+
그런데 객체를 복제하고 싶다면 어떻게 해야 할까요? 기존에 있던 객체와 똑같으면서 독립적인 객체를 만들고 싶다면 말이죠.
96
96
97
-
That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time.
97
+
방법은 있는데 자바스크립트는 객체 복제 내장 메서드를 지원하지 않기 때문에 조금 어렵습니다. 사실 객체를 복제해야 할 일은 거의 없습니다. 참조에 의한 복사로 해결 가능한 일이 대다수이죠.
98
98
99
-
But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level.
99
+
정말 복제가 필요한 상황이라면 새로운 객체를 만든 다음 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사하면 됩니다.
100
100
101
-
Like this:
101
+
아래와 같이 말이죠.
102
102
103
103
```js run
104
104
let user = {
@@ -107,59 +107,59 @@ let user = {
107
107
};
108
108
109
109
*!*
110
-
let clone = {}; //the new empty object
110
+
let clone = {}; //새로운 빈 객체
111
111
112
-
//let's copy all user properties into it
112
+
//빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
113
113
for (let key in user) {
114
114
clone[key] = user[key];
115
115
}
116
116
*/!*
117
117
118
-
//now clone is a fully independent object with the same content
119
-
clone.name="Pete"; //changed the data in it
118
+
//이제 clone은 완전히 독립적인 복제본이 되었습니다.
119
+
clone.name="Pete"; //clone의 데이터를 변경합니다.
120
120
121
-
alert( user.name ); //still John in the original object
121
+
alert( user.name ); //기존 객체에는 여전히 John이 있습니다.
122
122
```
123
123
124
-
Also we can use the method [Object.assign](mdn:js/Object/assign) for that.
124
+
[Object.assign](mdn:js/Object/assign)를 사용하는 방법도 있습니다.
125
125
126
-
The syntax is:
126
+
문법과 동작방식은 다음과 같습니다.
127
127
128
128
```js
129
129
Object.assign(dest, [src1, src2, src3...])
130
130
```
131
131
132
-
- The first argument`dest` is a target object.
133
-
- Further arguments`src1, ..., srcN` (can be as many as needed) are source objects.
134
-
- It copies the properties of all source objects `src1, ..., srcN` into the target`dest`. In other words, properties of all arguments starting from the second are copied into the first object.
135
-
- The call returns `dest`.
132
+
- 첫 번째 인수`dest`는 목표로 하는 객체입니다.
133
+
- 이어지는 인수`src1, ..., srcN`는 복사하고자 하는 객체입니다. `...`은 필요에 따라 얼마든지 많은 객체를 인수로 사용할 수 있다는 것을 나타냅니다.
134
+
- 객체 `src1, ..., srcN`의 프로퍼티를 `dest`에 복사합니다.`dest`를 제외한 인수(객체)의 프로퍼티 전부가 첫 번째 인수(객체)로 복사됩니다.
135
+
- 마지막으로 `dest`를 반환합니다.
136
136
137
-
For instance, we can use it to merge several objects into one:
137
+
`assign` 메서드를 사용해 여러 객체를 하나로 병합하는 예시를 살펴봅시다.
138
138
```js
139
139
let user = { name:"John" };
140
140
141
141
let permissions1 = { canView:true };
142
142
let permissions2 = { canEdit:true };
143
143
144
144
*!*
145
-
//copies all properties from permissions1 and permissions2 into user
145
+
//permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
146
146
Object.assign(user, permissions1, permissions2);
147
147
*/!*
148
148
149
149
// now user = { name: "John", canView: true, canEdit: true }
150
150
```
151
151
152
-
If the copied property name already exists, it gets overwritten:
152
+
목표 객체(`user`)에 동일한 이름을 가진 프로퍼티가 있는 경우엔 기존 값이 덮어씌워 집니다.
153
153
154
154
```js run
155
155
let user = { name:"John" };
156
156
157
157
Object.assign(user, { name:"Pete" });
158
158
159
-
alert(user.name); //now user = { name: "Pete" }
159
+
alert(user.name); // user = { name: "Pete" }
160
160
```
161
161
162
-
We also can use `Object.assign` to replace `for..in` loop for simple cloning:
162
+
`Object.assign`을 사용하면 반복문 없이도 간단하게 객체를 복사할 수 있습니다.
163
163
164
164
```js
165
165
let user = {
@@ -172,13 +172,13 @@ let clone = Object.assign({}, user);
172
172
*/!*
173
173
```
174
174
175
-
It copies all properties of `user` into the empty object and returns it.
175
+
예시를 실행하면 `user`에 있는 모든 프로퍼티가 빈 배열에 복사되고 변수에 할당됩니다.
176
176
177
-
## Nested cloning
177
+
## 중첩 객체 복사
178
178
179
-
Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them?
179
+
지금까진 `user`의 모든 프로퍼티가 원시값인 경우만 가정했습니다. 그런데 프로퍼티는 다른 객체에 대한 참조 값일 수도 있습니다. 이 경우는 어떻게 해야 할까요?
180
180
181
-
Like this:
181
+
아래와 같이 말이죠.
182
182
```js run
183
183
let user = {
184
184
name:"John",
@@ -191,9 +191,9 @@ let user = {
191
191
alert( user.sizes.height ); // 182
192
192
```
193
193
194
-
Now it's not enough to copy `clone.sizes=user.sizes`, because the `user.sizes` is an object, it will be copied by reference. So `clone` and `user` will share the same sizes:
194
+
`clone.sizes=user.sizes`로 프로퍼티를 복사하는 것만으론 객체를 복제할 수 없습니다. `user.sizes`는 객체이기 때문에 참조 값이 복사되기 때문입니다. `clone.sizes=user.sizes`로 프로퍼티를 복사하면 `clone`과 `user`는 같은 sizes를 공유하게 됩니다.
195
195
196
-
Like this:
196
+
아래와 같이 말이죠.
197
197
198
198
```js run
199
199
let user = {
@@ -213,16 +213,16 @@ user.sizes.width++; // change a property from one place
213
213
alert(clone.sizes.width); // 51, see the result from the other one
214
214
```
215
215
216
-
To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
216
+
이 문제를 해결하려면 `user[key]`의 각 값을 검사하면서 그 값이 객체라면 객체의 구조도 복사해주는 반복문을 사용해야 합니다. 이를 '깊은 복사(deep cloning)'라고 부릅니다.
217
217
218
-
There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data).
218
+
깊은 복사 시 사용되는 표준 알고리즘, [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data)을 사용하면 위 사례를 비롯한 다양한 상황에서 객체를 복제할 수 있습니다.
219
219
220
-
We can use recursion to implement it. Or, not to reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
220
+
자바스크립트 라이브러리 [lodash](https://lodash.com)의 메서드, [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep)을 사용하면 이 알고리즘을 직접 구현하지 않고도 깊은 복사를 처리할 수 있으므로 참고하시기 바랍니다.
221
221
222
-
## Summary
222
+
## 요약
223
223
224
-
Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object.
224
+
객체는 참조에 의해 할당되고 복사됩니다. 변수엔 '객체' 자체가 아닌 메모리상의 주소인 '참조'가 저장됩니다. 따라서 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사됩니다.
225
225
226
-
All operations via copied references (like adding/removing properties) are performed on the same single object.
226
+
그리고 복사된 참조를 이용한 모든 작업(프로퍼티 추가·삭제 등)은 동일한 객체를 대상으로 이뤄집니다.
227
227
228
-
To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
228
+
객체의 '진짜 복사본'을 만들려면 '얕은 복사(shallow copy)'를 가능하게 해주는 `Object.assign`이나 '깊은 복사(deep cloning)'를 가능하게 해주는 [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep)를 사용하면 됩니다. 이때 얕은 복사본은 중첩 객체를 처리하지 못한다는 점을 기억해 두시기 바랍니다.
0 commit comments