1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
---
title: Working with objects
slug: Web/JavaScript/Guide/Working_with_Objects
translation_of: Web/JavaScript/Guide/Working_with_Objects
---
<p>자바스크립트는 간단한 객체기반 패러다임 상에서 만들어졌다. 객체는 프로퍼티의 모음이며, 프로퍼티는 "이름"(name 또는 key)과 "값"(value)의 연결로 이루어진다 . 프로퍼티의 값으로 함수가 될 수 있는데, 이런 프로퍼티는 메소드라고 불린다. 브라우저 안에 미리 정의 된 객체뿐 아니라 사용자들이 직접 자신만의 객체를 정의할 수도 있다.</p>
<p class="summary">이 절에서는 객체, 프로퍼티, 함수, 메소드가 어떻게 사용되는지, 그리고 사용자를 위한 새로운 객체를 생성하는 방법을 설명한다</p>
<h2 id="개요">개요</h2>
<p>자바스크립트에서의 객체는 다른 프로그래밍 언어에서와 비슷하게 현실 세계에서의 사물(objects)과 비교해 볼 수 있다. 자바스크립트에서의 객체의 개념은 실세계상에서의 인식 가능한 사물로 이해할 수 있다.</p>
<p>객체는 단독으로 존재 가능한 개체(entity)이며, 프로퍼티(property)과 타입(type)을 가진다. 예를 들어 컵과 비교를 해 본다면 컵은 사물 객체인데 색깔, 모양, 무게, 재료 등의 속성(프로퍼티)을 가지고 있다. 비슷하게 자바스크립트의 객체는 그 특징을 결정짓는 여러 프로퍼티를 가진다.</p>
<h2 id="객체와_프로퍼티">객체와 프로퍼티</h2>
<p><span style="font-size: 14px; line-height: 1.5;">자바스크립트의 객체에는 그와 연관된 프로퍼티가 있다. 프로퍼티는 객체에 붙은 변수(variable)라고 설명할 수 있겠다. 객체의 프로퍼티는 일반 자바스크립의 변수와 기본적으로 똑같은데, 다만 객체에 속해있다는 차이만 있을 뿐이다. 객체의 프로퍼티들이 객체의 특징을 규정한다. 프로퍼티에 접근할 때는 도트(점) 표기법을 사용한다.</span></p>
<pre class="brush: js">objectName.propertyName
</pre>
<p><span style="font-size: 14.39px; line-height: 16.79px;">자바스크립트의 모든 변수가 그렇듯이, 객체의 이름과 프로퍼티 이름은 모두 대소문자를 구별한다. 프로퍼티를 새로 정의하려면 그냥 이름과 값을 추가하면 된다. 예를 들어</span><span style="font-size: 14px; line-height: 1.5;"> </span><code style="line-height: 1.5; font-size: 14px; font-style: normal;">myCar</code><span style="font-size: 14px; line-height: 1.5;"> </span><span style="font-size: 14.39px; line-height: 16.79px;">라는 이름의 객체를 생성하고, 거기에</span><span style="font-size: 14px; line-height: 1.5;"> </span><code style="line-height: 1.5; font-size: 14px; font-style: normal;">make</code><span style="font-size: 14px; line-height: 1.5;">, </span><code style="line-height: 1.5; font-size: 14px; font-style: normal;">model</code><span style="font-size: 14px; line-height: 1.5;">, and </span><code style="line-height: 1.5; font-size: 14px; font-style: normal;">year</code><span style="font-size: 14px; line-height: 1.5;"> </span><span style="font-size: 14.39px; line-height: 16.79px;">라는 프로퍼티들을 추가해보자:</span></p>
<pre class="brush: js">var myCar = new Object();
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;
</pre>
<p><span style="font-size: 14px; line-height: 1.5;">대괄호 표기법을 사용하여 객체의 프로퍼티에 접근할 수 있다. 객체는 연관배열(</span><em>associative arrays</em><span style="font-size: 14px; line-height: 1.5;">)이라고도 불리는데, 각 프로퍼티는 하나의 문자열 이름과 연관되어(associated) 이것을 통해 접근할 수 있기 때문이다. 예를 들면 </span><span style="font-family: courier new,andale mono,monospace; font-size: 14.39px; line-height: 16.79px;">myCar</span><span style="font-size: 14px; line-height: 1.5;"> 객체의 프로퍼티에 다음과 같이 접근할 수 있다.</span></p>
<pre class="brush: js">myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
</pre>
<p><span style="font-size: 14px; line-height: 1.5;">객체의 프로퍼티 이름은 유효한 자바스크립트 문자열이거나 문자열로 변환이 가능한 것이면 어떤 것이든 가능하며, 심지어 빈 문자열도 된다. 하지만 자바스크립트 식별자(identifier)로 적합하지 않으면 (예 : 하이픈, 빈칸을 포함하거나 숫자로 시작하는 이름), 대괄호를 이용한 표기법으로만 접근이 가능하다. 이 표기법은 프로퍼티 이름이 사전에 미리 결정되지 않고 런타임 시점에 결정되는 경우에 특히 유용하다. 아래의 예를 보자.</span></p>
<pre class="brush: js">var myObj = new Object(),
str = "myString",
rand = Math.random(),
obj = new Object(); // 변수 4개를 콤마를 사용하여 한번에 생성하고 할당.
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
console.log(myObj);
</pre>
<p><span style="font-size: 14px; line-height: 1.5;">변수에 저장된 문자열을 이용해서도 프로퍼티에 접근할 수 있다.</span></p>
<div style="width: auto;">
<pre class="brush: js">var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
</pre>
</div>
<p>대괄호 표기법을 <a class="internal" href="/ko/docs/JavaScript/Guide/Statements#for...in_Statement" title="ko/docs/JavaScript/Guide/Statements#for...in Statement">for...in</a> 과 함께 사용하면 객체의 열거가능한 프로퍼티를 나열할 수 있다. 이것이 어떻게 작동하는지 알기 위해 아래의 함수를 보자. 이 함수는 객체와 객체 이름을 함수의 인자로 전달받아서 객체의 프로퍼티들을 출력해 준다.</p>
<pre class="brush: js">function showProps(obj, objName) {
var result = "";
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
result += objName + "." + i + " = " + obj[i] + "\n";
}
}
return result;
}
</pre>
<p><code>showProps(myCar, "myCar")</code> 함수를 호출하면 다음과 같은 문자열을 반환한다.</p>
<pre>myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969</pre>
<h2 id="모든_것이_객체">모든 것이 객체</h2>
<p><span style="font-size: 14px; line-height: 1.5;">자바스크립트 세상에서는 거의 모든 것들이 객체이다. </span><code style="line-height: 16.79px; font-size: 14.39px; font-style: normal;">null</code><span style="font-size: 14.39px; line-height: 16.79px;"> 과 </span><code style="line-height: 16.79px; font-size: 14.39px; font-style: normal;">undefined</code><span style="font-size: 14.39px; line-height: 16.79px;"> 를 제외한 모든 </span><span style="font-size: 14px; line-height: 1.5;">원시 타입도 객체로 취급된다. 이러한 원시 타입들에도 프로퍼티가 추가될 수 있고 (설명 필요: </span><span style="font-size: 14.39px; line-height: 16.79px;">assigned properties of some types are not persistent), 모두 객체로서의 특징을 갖는다.</span></p>
<h2 id="객체의_프로퍼티_나열하기">객체의 프로퍼티 나열하기</h2>
<p><a href="/ko/docs/JavaScript/ECMAScript_5_support_in_Mozilla" title="ko/docs/JavaScript/ECMAScript 5 support in Mozilla">ECMAScript 5</a> 를 기준으로 객체의 프로퍼티를 나열/순회하는 방법이 세 가지 있다.</p>
<ul>
<li><a href="/ko/docs/JavaScript/Reference/Statements/for...in" title="ko/docs/JavaScript/Reference/Statements/for...in">for...in</a> 루프<br>
이 방법은 객체와 객체의 프로토타입 체인 상의 열거 가능한 모든 프로퍼티를 순회한다.</li>
<li><a href="/ko/docs/JavaScript/Reference/Global_Objects/Object/keys" title="ko/docs/JavaScript/Reference/Global Objects/Object/keys">Object.keys(o)</a><br>
이 메소드는 객체 <span style="font-family: courier new,andale mono,monospace; font-size: 14.39px; line-height: 16.79px;">o</span><span style="font-size: 14.39px; line-height: 16.79px;"> </span> 자체에 속한(즉 프로토타입 체인 상에 있는 것은 제외) 열거 가능한 프로퍼티 이름들("keys")의 배열을 반환한다.</li>
<li><a href="/ko/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" title="ko/docs/JavaScript/Reference/Global Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames(o)</a><br>
이 메소드는 객체 <span style="font-family: courier new,andale mono,monospace; font-size: 14.39px; line-height: 16.79px;">o</span> 자체의 모든 프로퍼티(열거 가능 여부에 무관) 이름들의 배열을 반환한다.</li>
</ul>
<p>ECMAScript 5 이전 버전에서는 객체의 모든 프로퍼티를 나열하는 자체적인 방법이 제공되지 않았다. 하지만 아래 함수를 이용하면 가능하다.</p>
<pre class="brush: js">function listAllProperties(o){
var objectToInspect;
var result = [];
for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
result = result.concat(Object.getOwnPropertyNames(objectToInspect));
}
return result;
}
</pre>
<p>이 트릭은 객체의 "숨겨진" 프로퍼티를 알아내는 데 유용하다. (숨겨진 프로퍼티란 프로토타입 체인 상의 프로퍼티 중 객체를 통해 접근이 불가능한 것들을 말하는데 동일 이름의 다른 프로퍼티가 프로퍼티 체인 상에서 먼저 존재하는 경우에 발생한다). 만약 접근 가능한 프로퍼티만 나열하고 싶다면 배열에서 중복되는 프로퍼티들을 제거하면 된다.</p>
<h2 id="객체_생성하기">객체 생성하기</h2>
<p>자바스크립트에는 미리 정의된 객체가 몇 개 존재한다. 사용자는 여기에 추가적으로 자신의 객체를 생성할 수 있다. 자바스크립트 1.2 부터는 객체 이니셜라이저(initializer) 를 이용하여 객체를 생성할 수 있다. 또 다른 방법으로는 먼저 생성자 함수를 정의한 후 이 함수와 <code style="font-style: normal;">new</code> 연산자를 이용하여 인스턴스를 만들수 있다.</p>
<p><span style="font-size: 1.71rem; letter-spacing: -0.5px; line-height: 24px;">객체 이니셜라이저</span></p>
<p>생성자 함수를 사용하는 방법 대신, 객체 이니셜라이저를 사용하여 객체를 생성할 수 있다. 이 방식은 때때로 "리터럴 표기에 의한 객체 생성"(creating objects with literal notation) 이라고도 불린다. 객체 이니셜라이저라는 단어는 C++ 에서도 비슷한 의미로 사용된다.</p>
<p><span style="line-height: 1.5;">객체 이니셜라이저를 이용한 객체 생성의 문법은 다음과 같다.</span></p>
<pre class="brush: js">var obj = { property_1: value_1, // property_# may be an identifier...
2: value_2, // or a number...
// ...,
"property n": value_n }; // or a string </pre>
<p><code>obj</code>는 새로 만들어질 객체 이름이고, <code>property_<em>i</em></code>는 식별자 (이름, 숫자, 또는 스트링 리터럴), <code style="font-style: normal;">value_<em>i</em></code> 는 수식인데 이 값이 <code>property_<em>i</em></code> 에 할당 된다. <code>obj</code> 변수에 할당 (assignment =) 하는 것은 선택 사항이다; 이 생성된 객체를 다른 곳에서 참조할 필요가 없다면 변수에 할당하지 않아도 된다. (만약 이 생성된 객체를 변수를 사용하지 않고 구문 안에서 바로 사용하려면 블럭 구문과 혼돈되지 않도록 리터널을 괄호로 감싸줄 필요가 있다.)</p>
<p>객체 이니셜라이저는 수식이고, 각각의 이니셜라이저가 포함된 구문이 실행될 때 마다 이니셜라이저 수식에 의해 새로운 객체가 하나씩 생성이 된다. 똑같은 이니셜라이저에 의해 생성된 객체라도 서로 별개이며 비교 결과는 동일하지 않음 (not equal) 이 된다. 객체는 마치 <code>new Object()</code> 호출이 실행된 것 처럼 생성이 된다; 즉, 객체 이니셜라이저 수식에 의해 만들어진 객체들은 <code>Object</code>의 인스턴스들이 된다.</p>
<p>다음 문장은 수식<code>cond</code>가 참일 경우 객체를 만들어서 변수 <code>x</code> 에 할당한다:</p>
<pre class="brush: js">if (cond) var x = {hi: "there"};
</pre>
<p>다음 예제는 <code>myHonda</code>을 생성하고 세개의 속성을 추가한다. <code>engine</code> 속성 역시 자신의 속성들을 가지고 있는 객체이다.</p>
<pre class="brush: js">var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};
</pre>
<p>객체 이니셜라이저를 이용하여 배열을 만들 수 있다. <a href="/ko/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Array_literals">array literals</a> 를 참조하기 바란다.</p>
<p>JavaScript 1.1 과 그 이전 버전에서는, 객체 이니셜라이저를 사용할 수 없었다. 항상 생성자 함수를 쓰거나 생성 목적으로 제공되는 별도 함수를 사용했어야 했다. <a href="/ko/docs/Web/JavaScript/Guide/Working_with_Objects#Using_a_constructor_function">Using a constructor function</a> 참고.</p>
<h3 id="생성자_함수_사용하기">생성자 함수 사용하기</h3>
<p>다른 방법으로는 다음 두 단계에 따라 객체를 생성할 수 있다:</p>
<ol>
<li>생성자 함수를 작성하여 객체 타입을 정의한다. 객체 타입 이름의 첫 글자는 반드시 대문자를 사용하는 좋은 관례가 있으므로 따르기를 권장한다.</li>
<li><code>new</code>를 이용하여 객체의 인스턴스를 생성한다.</li>
</ol>
<p>객체의 타입을 정의하려면 타입의 이름, 속성(프로퍼티), 메소드 등을 기술하는 함수를 하나 만들어야 한다. 예를 들면, 여러분이 자동차를 위한 객체 타입을 만들기 원한다면, 이 객체의 타입의 이름은 <code>car</code>이고, 이 타입은 제조사, 모델, 생산연도를 위한 속성을 포함하길 원할 것이다. 아마도 다음과 같은 함수를 작성하게 될 것이다:</p>
<pre class="brush: js">function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
</pre>
<p>함수 인자로 전달 받은 값을 객체의 속성에 할당하기 위해서 <code>this</code>를 사용 한 것에 주목하기 바란다.</p>
<p>이제 다음과 같이 하여 <code>mycar</code>라는 이름의 객체를 생성할 수 있다:</p>
<pre class="brush: js">var mycar = new Car("Eagle", "Talon TSi", 1993);
</pre>
<p>이 문장은 <code>mycar</code>를 만들고 특정 값들을 속성으로 할당하고 있다. 이렇게 하면 <code>mycar.make</code>의 값은 문자열 "Eagle" 이 되고, <code>mycar.year</code>는 정수 1993 이 된다.</p>
<p><code>new</code>를 이용하면 어떤 갯수의 <code>car</code> 객체도 만들 수 있다. 예를 들면 다음과 같다.</p>
<pre class="brush: js">var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);
</pre>
<p>객체는 또 다른 객체를 속성으로 가질 수 있다. 예를 들어 여러분이 <code>person</code> 이라는 객체를 다음과 같이 정의를 했고:</p>
<pre class="brush: js">function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
</pre>
<p>그리고 두 개의 새 <code>person</code> 객체의 인스턴스를 만들었다고 하면:</p>
<pre class="brush: js">var rand = new Person("Rand McKinnon", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
</pre>
<p><code>car</code>의 정의에 <code>person</code> 객체의 값을 갖는 <code>owner</code> 속성을 추가하도록 수정할 수 있다:</p>
<pre class="brush: js">function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
}
</pre>
<p>수정된 새 객체의 인스턴스를 만들려면 다음과 같이 하면 된다:</p>
<pre class="brush: js">var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
</pre>
<p>위 문장은 문자열 리터럴이나 정수를 넘기는 대신 객체 <code>rand</code> 와 <code>ken</code>을 owners를 위한 인자로 전달하고 있다. car2의 소유자 이름을 찾고 싶다면 다음과 같은 속성을 사용할 수 있다.:</p>
<pre class="brush: js">car2.owner.name
</pre>
<p>이미 정의 된 객체에도 새로운 속성을 추가할 수 있다.</p>
<pre class="brush: js">car1.color = "black";
</pre>
<p>위 문장은 속성 <code>color</code>를 car1 에 추가하고, 그 값으로는 "black"을 지정하고 있다. 그러나 이것은 다른 객체들에는 영향을 주지 않는다. 새 속성을 해당 타입의 모든 객체들에 다 추가하고 싶다면, 이 속성을 <code>car</code> 객체 타입의 정의에 추가해야 한다.</p>
<h3 id="Object.create_메서드_사용하기">Object.create 메서드 사용하기</h3>
<p>객체는 <code>Object.create</code> 메서드를 이용해서 생성될 수 있다. 이 메서드는 사용할 프로토타입 객체를 사용자가 직접 선택할 수 있기 때문에 상당히 유용하다. (객체 생성시 생성자 함수가 없어도 가능하다). 이 메서드에 대한 더 자세한 정보는 {{jsxref("Object.create()")}} 를 참고하도록 하자.</p>
<pre class="brush: js">// Animal properties and method encapsulation
var Animal = {
type: "Invertebrates", // Default value of properties
displayType : function(){ // Method which will display type of Animal
console.log(this.type);
}
}
// Create new animal type called animal1
var animal1 = Object.create(Animal);
animal1.displayType(); // Output:Invertebrates
// Create new animal type called Fishes
var fish = Object.create(Animal);
fish.type = "Fishes";
fish.displayType(); // Output:Fishes</pre>
<h2 id="상속">상속</h2>
<p>JavaScript 에서의 모든 객체들은 최소한 하나의 다른 객체로부터 상속을 받는다. 상속을 제공하는 객체를 프로토타입이라고 부르며, 상속되는 속성들은 <code>prototype</code> 이라는 생성자 객체에서 찾을 수 있다.</p>
<h2 id="객체_프로퍼티의_인덱싱">객체 프로퍼티의 인덱싱</h2>
<p>JavaScript 1.0에서는 객체의 속성을 참조할 때 속성 이름을 이용하거나 또는 숫자 인덱스를 이용할 수 있었다. 하지만 JavaScript 1.1과 그 이후 부터는 처음에 프로퍼티를 이름으로 정의하면 항상 이름으로만 참조를 할 수 있고, 처음에 인덱스를 이용하여 정의하면 인덱스를 이용해서만 참조할 수 있다.</p>
<p>이 제약 사항은 생성자 함수를 이용하여 객체와 프로퍼티를 생성할 때 (앞에서 <code>Car</code> 객체 타입의 예)에도 동일하게 적용되고, 개개의 속성을 명시적으로 지정할 때 (예: <code>myCar.color = "red"</code>)에도 마찬가지이다. 만약 처음에 객체 속성을 정의할 때 <code>myCar[5] = "25 mpg"</code> 처럼 인덱스 방식을 사용하면, 그 이후에도 계속 <code>myCar[5]</code> 방식으로만 참조할 수 있다.</p>
<p><code>forms</code> 배열과 같이 HTML 로부터 얻어지는 객체들에는 이 규칙이 적용되지 않는다. 숫자를 이용하거나 (이 객체가 문서 상에 존재하는 순서에 따라) 또는 태그의 attribute 이름으로 참조가 가능하다. 예를 들면 HTML 문서에서 두 번째 <code><FORM></code> 태그가 "myForm" 이라는 값의 <code>NAME</code> attribute 를 가지고 있다면, 이 form을 <code>document.forms[1]</code> 또는 <code>document.forms["myForm"]</code> 또는 <code>document.myForm</code> 와 같이 접근할 수 있다.</p>
<h2 id="객체의_프로퍼티_정의">객체의 프로퍼티 정의</h2>
<p><code>prototype</code> 프로퍼티를 사용하여 미리 정의된 객체 타입에 속성을 추가할 수 있다. 이렇게 정의된 속성은 해당 객체 타입의 한 인스턴스에만 적용되는 것이 아니라 해당 객체 타입의 모든 인스턴스가 갖게 된다. 다음 코드에서는 <code>car</code> 타입의 객체 전체에 <code>color</code> 프로퍼티를 추가한 후, <code>car1</code> 인스턴스의 <code>color</code> 프로퍼티에 값을 할당하는 것을 보여준다.</p>
<pre class="brush: js">Car.prototype.color = null;
car1.color = "black";
</pre>
<p>더 많은 정보는 <a href="/en-US/docs/JavaScript/Reference" title="en-US/docs/JavaScript/Reference">JavaScript Reference</a>에서 <code>Function</code> 객체의 <a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function/prototype">prototype 속성</a>을 참조</p>
<h2 id="메소드_정의">메소드 정의</h2>
<p><em>메소드</em>는 한 객체와 연관된(associated) 함수이며, 간단하게 말해 객체의 프로퍼티 중에서 함수인 것을 메소드라고 한다. 메소드를 정의하는 방식은 일반 함수를 정의하는 것과 동일하고, 다만 어떤 객체의 프로퍼티로 할당되어야 한다는 점이 차이가 난다. 자세한 것은 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a>를 참조하자. 다음은 메소드 정의의 한 예이다.</p>
<pre class="brush: js">objectName.methodname = function_name;
var myObj = {
myMethod: function(params) {
// ...do something
}
};
</pre>
<p>첫번째 줄은 이미 존재하는 <code>objectName</code>이라는 객체에 <code>methodname</code>이라는 이름의 메소드를 추가하는 것이다. <code>function_name</code> 은 메소드로 사용될 함수의 이름이다. 두번째 줄부터는 객체를 정의할 때 메소드를 같이 정의하는 예이다.</p>
<p>그러고 나면 다음과 같이 해당 객체의 문맥(context)에서 메소드를 호출할 수 있다.</p>
<pre class="brush: js">object.methodname(params);
</pre>
<p>객체 생성자 함수에 메소드 정의를 포함시킴으로써 해당 객체 타입의 메소드를 정의할 수 있다. 한 예로 이전에 정의한 car 객체의 프로퍼티를 형식에 맞춰 출력하는 함수를 정의할 수 있는데, 다음과 같다.</p>
<pre class="brush: js">function displayCar() {
var result = "A Beautiful " + this.year + " " + this.make
+ " " + this.model;
pretty_print(result);
}
</pre>
<p>위에서 <code>pretty_print</code>는 수평 규칙과 문자열을 나타내 주는 함수이다. 여기서 사용한 <code>this</code>는 해당 메소드가 속한 객체를 가리킨다는 점을 기억하자.</p>
<p>아래와 같은 코드를 <code>car</code>객체의 정의에 추가함으로써 해당 함수를 <code>car</code>객체의 메소드로 만들 수 있다.</p>
<pre class="brush: js">this.displayCar = displayCar;
</pre>
<p>따라서 <code>car객체의 전체 정의는 아래와 같이 됩니다.</code></p>
<pre class="brush: js">function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
this.displayCar = displayCar;
}
</pre>
<p>그리고 각각의 객체(인스턴스)를 가지고 <code>displayCar메서드를 아래와 같이 호출 할 수 있습니다:</code></p>
<pre class="brush: js">car1.displayCar();
car2.displayCar();
</pre>
<h2 id="객체_참조를_위해_this_를_사용하기">객체 참조를 위해 <code>this</code> 를 사용하기</h2>
<p>자바스크립트는 특별한 키워드를 가지고 잇습니다. 바로 <code>this</code>라는 키워드이다. 메서드 내부에서 <code>this 키워드를 사용하게 되면 해당 메서드를 포함한 객체를 가리키게 된다. 예를 들어 특정 객체의 속성값의 상한과 하한 값의 범위에 있는지를 확인하는 validate라는 함수를 아래와 같이 작성한다고 했을 때, </code></p>
<pre class="brush: js">function validate(obj, lowval, hival) {
if ((obj.value < lowval) || (obj.value > hival))
alert("Invalid Value!");
}
</pre>
<p><code>validate메서드를 각각의 form 요소들의 onchange 이벤트 핸들러에서 호출할 수 있다. 그 때, 다음 예제처럼 this 키워드를 사용해서 해당 form요소를 인자로 넘길 수 있다. </code></p>
<pre class="brush: html"><input type="text" name="age" size="3"
onChange="validate(this, 18, 99)">
</pre>
<p>일반적으로 <code>this는 메서드를 호출하는 객체를 지칭합니다. </code></p>
<p> <code>myForm</code>. <code>form속성과 함께 사용할때, this키워드는 현재 객체의 부모 form을 지칭한다. 다음의 예제에서, myForm form은 텍스트 객체와 버튼 객체를 가지고 있다. 사용자가 해당 버튼을 클릭했을때, myForm form안에 있는 텍스트 객체의 값을 myForm form의 이름으로 설정한다. 해당 버튼의 onclick 이벤트 처리자는 부모 form인 myForm을 지칭하기 위해 this.form를 사용한다. </code></p>
<pre class="brush: html"><form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
onclick="this.form.text1.value = this.form.name">
</p>
</form></pre>
<h2 id="getters_와_setters_정의">getters 와 setters 정의</h2>
<p><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> 메서드는 특정 속성의 값을 받아 오기 위한 메서드 입니다. <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a>메서드는 특정 속성의 값을 설정하기 위한 메서드 입니다. 새로운 속성을 추가 하기 위해 getter와 setter 메서드들을 미리 정의된 객체 혹은 사용자 정의 객체에 정의 하 수 있습니다. getter와 setter메서드들을 정의 하기 위한 문법은 객체 구문 문법을 사용합니다.</p>
<p>자바스크립트 1.8.1버전부터, 객체와 배열 초기화에서 속성들을 설정하고자 할 경우 setter메서드들은 더이상 사용이 불가합니다.</p>
<p>다음의 <a href="/en-US/docs/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="en-US/docs/SpiderMonkey/Introduction to the JavaScript shell">JS 쉘</a>은 getter와 setter메서드들이 사용자 정의객체인 o에서 어떻게 작동하는지를 보여 줍니다. JS쉘은 개발자가 배치 모드 혹은 대화형 모드에서 자바스크립트 코드를 테스트하기위한 하나의 어플리케이션입니다. </p>
<pre class="brush: js">js> var o = {a: 7, get b() {return this.a + 1;}, set c(x) {this.a = x / 2}};
[object Object]
js> o.a;
7
js> o.b;
8
js> o.c = 50;
js> o.a;
25
</pre>
<p>o 객체의 속성이 다음과 같을 때,</p>
<ul>
<li><code>o.a</code> — 숫자</li>
<li><code>o.b</code> — o.a에 1을 더한 값을 반환하는 getter 메서드</li>
<li><code>o.c</code> — <code>o.a에 주어진 인자 값의 반에 해당 하는 값을 설정하는 setter 메서드</code></li>
</ul>
<p><code>[gs]et <em>속성명</em>()</code> 문법이 실제 사용되는 메서드명이라고 생각이 될지라도, "[gs]et <em>속성명</em>()" 문법(<code>__define[GS]etter__와는 반대로</code>)을 사용한 객체 구문 문법으로 정의된 getter와 setter메서드들의 이름들은 실제 getter 메서드들의 이름이 아니라는 점에 유의 하세요. "[gs]et <em>속성명</em>()" 문법을 사용하여 getter, setter메서드내의 함수명을 작성하기 위해서는, <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty" title="en-US/docs/Core JavaScript 1.5 Reference/Global
Objects/Object/defineProperty">Object.defineProperty</a></code> (혹은 <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineGetter" title="en-US/docs/Core JavaScript 1.5 Reference/Global
Objects/Object/defineGetter">Object.prototype.__defineGetter__</a> 레거시 콜백</code>)을 사용하여 프로그램적으로 분명한 이름의 함수명을 사용하세요. </p>
<p>아래의 자바스크립트 쉡은 이미 정의된 Date 클래스의 모든 인스턴스들에 년도 속성을 추가 하기 위해 getter와 setter 메서드들이 Date 프로토타입을 확장하는 방법을 보여 줍니다. </p>
<p>아래의 구문들은 년도 속성 추가를 위한 getter와 setter메서드를 정의합니다:</p>
<pre class="brush: js">js> var d = Date.prototype;
js> Object.defineProperty(d, "year", {
get: function() {return this.getFullYear() },
set: function(y) { this.setFullYear(y) }
});
</pre>
<p>아래의 구문들은 Date객체에서 getter와 setter메서드를 사용하는 법을 보여 줍니다:</p>
<pre class="brush: js">js> var now = new Date;
js> print(now.year);
2000
js> now.year = 2001;
987617605170
js> print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
</pre>
<p>원칙적으로, getter와 setter는 둘 중 하나가 될 수 있다.</p>
<ul>
<li>object initializers 를 사용하여 정의하거나, </li>
<li>getter와 setter메서드 추가 방법을 사용하여 언제든지 특정 객체에 나중에 추가하는 방법</li>
</ul>
<p>object initializers를 사용해서 getter와 setter메서드들을 정의할 경우, getter메서드는 get, setter메서드는 set이라는 접두사만 추가하면 됩니다. 물론 getter메서드는 인자를 받지 않는 반면, setter 메서드는 정확히 하나의 인자(설정할 새로운 값)만을 받습니다. </p>
<pre class="brush: js">var o = {
a: 7,
get b() { return this.a + 1; },
set c(x) { this.a = x / 2; }
};
</pre>
<p><code>Object.defineProperties 메서드를 사용하면 객체 생성이후라도 언제든지 </code>getter and setter메서드들을 객체에 추가할 수 있습니다. <code>Object.defineProperties 메서드의 첫번째 인자는 </code>getter and setter메서드들을 추가할 객체이고, 두번째 인자는 getter and setter메서드들의 이름과 getter and setter메서드들의 정의를 가지고 있는 객체가 되어야 합니다. 이전 예제와 동일하게 사용된 getter and setter메서드들을 정의하고 있는 예제는 아래와 같습니다:</p>
<pre class="brush: js">var o = { a:0 }
Object.defineProperties(o, {
"b": { get: function () { return this.a + 1; } },
"c": { set: function (x) { this.a = x / 2; } }
});
o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.b) // Runs the getter, which yields a + 1 or 6
</pre>
<p>당신의 프로그래밍 스타일과 현재 진행 중인 작업에 따라 getter and setter메서드들을 정의할 수 있는 두가지 양식 중 하나를 선택하여 사용할 수 있습니다. prototype을 정의 할때 object initializer를 사용했다면 앞으로도 대부분 첫번째 양식을 선택 하여 작성을 할 것입니다. 이 양식이 보다 간결하고 자연스럽기 때문입니다. 하지만 prototype 혹은 특정 객체를 작성하지 않고서 나중에 getter and setter 메서드를 추가하고자 한다면 두번째 양식만이 가능한 선택입니다. 두번째 양식은 아마도 자바스크립트의 동적 속성을 가장 잘 나타내고 있습니다. 하지만 코드 작성과 읽고 이해하는 부분에 어려움이 있습니다. </p>
<div class="note">
<p>Firefox 3.0 이전 버전의 경우, getter and setter 메서드들은 DOM 요소들에는 지원되지 않습니다. 이전 버전의 Firefox에서는 아무런 에러 없이 작동하지 않을 것입니다. 이것에 대한 예외가 필요하다면, HTMLElement의 prototype<code>(HTMLElement.prototype.__define[SG]etter__)</code>을 변경하고 예외를 던지는 것이 하나의 방법입니다.</p>
<p>Firefox 3.0 버전에서는 이미 정의된 속서에 대해 getter or setter를 정의 할 경우 예외가 발생됩니다. 이전 버전의 Firefox에서는 아니지만 해당 속성을 반드시 사전에 제거해야만 합니다. </p>
</div>
<h4 id="Defining_getters_and_setters_See_also" name="Defining_getters_and_setters_See_also">추가로 볼 것들 </h4>
<ul>
<li><code><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty" title="en-US/docs/JavaScript/Reference/Global_Objects/Object/defineSetter">Object.defineProperty</a></code></li>
<li><code><a href="/en-US/docs/JavaScript/Reference/Operators/get" title="en-US/docs/JavaScript/Reference/Operators/Special Operators/get Operator">get</a></code></li>
<li><code><a href="/en-US/docs/JavaScript/Reference/Operators/set" title="en-US/docs/JavaScript/Reference/Operators/Special Operators/set Operator">set</a></code></li>
</ul>
<h2 id="프로퍼티의_삭제">프로퍼티의 삭제</h2>
<p>상속 받지 않은 속성은 <code>delete</code> 연산자를 이용하여 제거 할 수 있다. 다음 코드는 어떻게 속성을 제거하는지 보여준다.</p>
<pre class="brush: js">// 새 객체 myobj를 두 개의 속성 a, b 와 함께 생성
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;
// 속성을 삭제. myobj 에는 속성 b 만 남게 됨.
delete myobj.a;
console.log ("a" in myobj) // "false"를 출력
</pre>
<p><code>var</code> 키워드로 선언하지 않은 전역 변수도 <code>delete</code>를 이용하여 삭제를 할 수 있다:</p>
<pre class="brush: js">g = 17;
delete g;
</pre>
<p>더 자세한 정보는 <code><a href="/ko/docs/Web/JavaScript/Reference/Operators/delete">delete</a></code>를 보면 된다.</p>
<h2 id="객체_간의_비교">객체 간의 비교</h2>
<p>JavaScript 에서는 객체들은 레퍼런스 타입이다. 두 개의 별개 객체들은, 설령 그 속성 값들이 모두 다 동일하다고 하더라도, 절대로 동일하다고 비교(equal)될 수 없다. In JavaScript objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true.</p>
<pre class="brush: js">// 속성은 같지만 서로 별개인 두 변수와 두 객체
var fruit = {name: "apple"};
var fruitbear = {name: "apple"};
fruit == fruitbear // false 리턴
fruit === fruitbear // false 리턴</pre>
<pre class="brush: js">// 두 개의 변수이지만 하나의 객체
var fruit = {name: "apple"};
var fruitbear = fruit; // fruit 객체 레퍼런스를 fruitbear 에 할당
// here fruit and fruitbear are pointing to same object
fruit == fruitbear // true 리턴
fruit === fruitbear // true 리턴
</pre>
<p>비교 연산자에 대한 상세한 정보는 <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">Comparison operators</a>를 참고하기 바란다.</p>
<h2 id="추가_검토">추가 검토</h2>
<ul>
<li><a class="external" href="http://es5.github.com/#x4.2" title="http://es5.github.com/#x4.2">ECMAScript 5.1 spec: Language Overview</a></li>
<li><a class="external" href="http://dmitrysoshnikov.com/ecmascript/javascript-the-core" title="http://dmitrysoshnikov.com/ecmascript/javascript-the-core">JavaScript. The core. (Dmitry A. Soshnikov ECMA-262 article series)</a></li>
</ul>
<div>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</div>
|