aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/javascript/reference/operators/object_initializer/index.html
blob: c8e4308f32e72eb51154c935c916cedcace80b9c (plain)
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
---
title: Object initializer
slug: Web/JavaScript/Reference/Operators/Object_initializer
translation_of: Web/JavaScript/Reference/Operators/Object_initializer
---
<div>{{JsSidebar("Operators")}}</div>

<p>Objects can be initialized using <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object"><code>new Object()</code></a>,<code> <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code>, or using the <em>literal</em> notation (<em>initializer</em> notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces (<code>{}</code>).</p>

<h2 id="語法">語法</h2>

<pre class="brush: js">var o = {};
var o = {a: 'foo', b: 42, c: {}};

var a = 'foo', b = 42, c = {};
var o = {a: a, b: b, c: c};

var o = {
  <var>property: function </var>([<var>parameters</var>]) {},
  get <var>property</var>() {},
  set <var>property</var>(<var>value</var>) {}
};
</pre>

<h3 id="New_notations_in_ECMAScript_2015">New notations in ECMAScript 2015</h3>

<p>Please see the compatibility table for support for these notations. In non-supporting environments, these notations will lead to syntax errors.</p>

<pre class="brush: js">// Shorthand property names (ES2015)
var a = 'foo', b = 42, c = {};
var o = {a, b, c};

// Shorthand method names (ES2015)
var o = {
  <var>property</var>([<var>parameters</var>]) {}
};

// Computed property names (ES2015)
var prop = 'foo';
var o = {
  [prop]: 'hey',
  ['b' + 'ar']: 'there'
};</pre>

<h2 id="說明">說明</h2>

<p>An object initializer is an expression that describes the initialization of an {{jsxref("Object")}}. Objects consist of <em>properties</em>, which are used to describe an object. Values of object properties can either contain {{Glossary("primitive")}} data types or other objects.</p>

<h3 id="建立物件">建立物件</h3>

<p>An empty object with no properties can be created like this:</p>

<pre class="brush: js">var object = {};</pre>

<p>However, the advantage of the <em>literal</em> or <em>initializer</em> notation is, that you are able to quickly create objects with properties inside the curly braces. You simply notate a list of <code>key: value</code> pairs delimited by comma. The following code creates an object with three properties and the keys are <code>"foo"</code>, <code>"age"</code> and <code>"baz"</code>. The values of these keys are a string <code>"bar"</code>, a number <code>42</code> and the third property has another object as its value.</p>

<pre class="brush: js">var object = {
  foo: 'bar',
  age: 42,
  baz: {myProp: 12}
}</pre>

<h3 id="存取屬性">存取屬性</h3>

<p>Once you have created an object, you might want to read or change them. Object properties can be accessed by using the dot notation or the bracket notation. See <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessors</a> for detailed information.</p>

<pre class="brush: js">object.foo; // "bar"
object['age']; // 42

object.foo = 'baz';
</pre>

<h3 id="屬性定義">屬性定義</h3>

<p>We have already learned how to notate properties using the initializer syntax. Oftentimes, there are variables in your code that you would like to put into an object. You will see code like this:</p>

<pre class="brush: js">var a = 'foo',
    b = 42,
    c = {};

var o = {
  a: a,
  b: b,
  c: c
};</pre>

<p>With ECMAScript 2015, there is a shorter notation available to achieve the same:</p>

<pre class="brush: js">var a = 'foo',
    b = 42,
    c = {};

// Shorthand property names (ES2015)
var o = {a, b, c};

// In other words,
console.log((o.a === {a}.a)); // true
</pre>

<h4 id="Duplicate_property_names">Duplicate property names</h4>

<p>When using the same name for your properties, the second property will overwrite the first.</p>

<pre class="brush: js">var a = {x: 1, x: 2};
console.log(a); // {x: 2}
</pre>

<p>In ECMAScript 5 strict mode code, duplicate property names were considered a {{jsxref("SyntaxError")}}.  With the introduction of computed property names making duplication possible at runtime, ECMAScript 2015 has removed this restriction.</p>

<pre class="brush: js">function haveES2015DuplicatePropertySemantics() {
  'use strict';
  try {
    ({prop: 1, prop: 2});

    // No error thrown, duplicate property names allowed in strict mode
    return true;
  } catch(e) {
    // Error thrown, duplicates prohibited in strict mode
    return false;
  }
}</pre>

<h3 id="方法定義">方法定義</h3>

<p>A property of an object can also refer to a <a href="/en-US/docs/Web/JavaScript/Reference/Functions">function</a> or a <a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> or <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a> method.</p>

<pre class="brush: js">var o = {
  <var>property: function </var>([<var>parameters</var>]) {},
  get <var>property</var>() {},
  set <var>property</var>(<var>value</var>) {}
};</pre>

<p>In ECMAScript 2015, a shorthand notation is available, so that the keyword "function" is no longer necessary.</p>

<pre class="brush: js">// Shorthand method names (ES2015)
var o = {
  <var>property</var>([<var>parameters</var>]) {},
  *<var>generator</var>() {}
};</pre>

<p>In ECMAScript 2015 There is a way to concisely define properties whose values are generator functions:</p>

<pre class="brush: js">var o = {
  *<var>generator</var>() {
    ...........
  }
};</pre>

<p>Which is equivalent to this ES5-like notation (but note that ECMAScript 5 has no generators):</p>

<pre class="brush: js">var o = {
  generator<var>: function* </var>() {
    ...........
  }
};</pre>

<p>For more information and examples about methods, see <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a>.</p>

<h3 id="Computed_property_names">Computed property names</h3>

<p>Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets <code>[]</code>, that will be computed as the property name. This is symmetrical to the bracket notation of the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessor</a> syntax, which you might have used to read and set properties already. Now you can use the same syntax in object literals, too:</p>

<pre class="brush: js">// Computed property names (ES2015)
var i = 0;
var a = {
  ['foo' + ++i]: i,
  ['foo' + ++i]: i,
  ['foo' + ++i]: i
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

var param = 'size';
var config = {
  [param]: 12,
  ['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
};

console.log(config); // {size: 12, mobileSize: 4}</pre>

<h3 id="Spread_properties">Spread properties</h3>

<p>The <a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript</a> proposal (stage 3) adds <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread</a> properties to object literals. It copies own enumerable properties from a provided object onto a new object.</p>

<p>Shallow-cloning (excluding prototype) or merging objects is now possible using a shorter syntax than {{jsxref("Object.assign()")}}.</p>

<pre class="brush: js">var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }</pre>

<p>Note that {{jsxref("Object.assign()")}} triggers <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setters</a> whereas the spread operator doesn't.</p>

<h3 id="Prototype_mutation">Prototype mutation</h3>

<p>A property definition of the form <code>__proto__: value</code> or <code>"__proto__": value</code> does not create a property with the name <code>__proto__</code>.  Instead, if the provided value is an object or <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a>, it changes the <code>[[Prototype]]</code> of the created object to that value.  (If the value is not an object or null, the object is not changed.)</p>

<pre class="brush: js">var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

var obj2 = {__proto__: null};
assert(Object.getPrototypeOf(obj2) === null);

var protoObj = {};
var obj3 = {'__proto__': protoObj};
assert(Object.getPrototypeOf(obj3) === protoObj);

var obj4 = {__proto__: 'not an object or null'};
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty('__proto__'));
</pre>

<p>Only a single prototype mutation is permitted in an object literal: multiple prototype mutations are a syntax error.</p>

<p>Property definitions that do not use "colon" notation are not prototype mutations: they are property definitions that behave identically to similar definitions using any other name.</p>

<pre class="brush: js">var __proto__ = 'variable';

var obj1 = {__proto__};
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty('__proto__'));
assert(obj1.__proto__ === 'variable');

var obj2 = {__proto__() { return 'hello'; }};
assert(obj2.__proto__() === 'hello');

var obj3 = {['__prot' + 'o__']: 17};
assert(obj3.__proto__ === 17);
</pre>

<h2 id="Object_literal_notation_vs_JSON">Object literal notation vs JSON</h2>

<p>Object literal notation與<strong>J</strong>ava<strong>S</strong>cript <strong>O</strong>bject <strong>N</strong>otation (<a href="/en-US/docs/Glossary/JSON">JSON</a>)是不一樣的東西. 儘管它們看起來很相似,但還是有以下的不同:</p>

<ul>
 <li>JSON只允許屬性透過<code>"property": value</code>格式定義. 屬性名稱必須使用雙引號包起來,且不能是速記。</li>
 <li>JSON的數值僅能為string, numbers, arrays, <code>true</code>, <code>false</code>, <code>null</code>, 或另一個JSON物件.</li>
 <li>A function value (see "Methods" above) can not be assigned to a value in JSON.</li>
 <li>Objects like {{jsxref("Date")}} will be a string after {{jsxref("JSON.parse()")}}.</li>
 <li>{{jsxref("JSON.parse()")}} will reject computed property names and an error will be thrown.</li>
</ul>

<h2 id="規範">規範</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES1')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a> added.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-object-initializer', 'Object Initializer')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Shorthand method/property names and computed property names added.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td><a href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript </a></td>
   <td>Draft</td>
   <td>Stage 3 draft.</td>
  </tr>
 </tbody>
</table>

<h2 id="瀏覽器相容性">瀏覽器相容性</h2>

<div>{{CompatibilityTable}}</div>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Edge</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatChrome(1.0)}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoDesktop("1.0")}}</td>
   <td>1</td>
   <td>1</td>
   <td>1</td>
  </tr>
  <tr>
   <td>Computed property names</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoDesktop("34")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>7.1</td>
  </tr>
  <tr>
   <td>Shorthand property names</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoDesktop("33")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>9</td>
  </tr>
  <tr>
   <td>Shorthand method names</td>
   <td>{{CompatChrome(42.0)}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoDesktop("34")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>9</td>
  </tr>
  <tr>
   <td>Spread properties</td>
   <td>{{CompatChrome(60)}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoDesktop("55")}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Android Webview</th>
   <th>Edge</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
   <th>Chrome for Android</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoMobile("1.0")}}</td>
   <td>1</td>
   <td>1</td>
   <td>1</td>
   <td>{{CompatChrome(1.0)}}</td>
  </tr>
  <tr>
   <td>Computed property names</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoMobile("34")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>7.1</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td>Shorthand property names</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoMobile("33")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>9</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td>Shorthand method names</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(42.0)}}</td>
   <td>{{CompatVersionUnknown}}</td>
   <td>{{CompatGeckoMobile("34")}}</td>
   <td>{{CompatNo}}</td>
   <td>34</td>
   <td>9</td>
   <td>{{CompatChrome(42.0)}}</td>
  </tr>
  <tr>
   <td>Spread properties</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoMobile("55")}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="參見">參見</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">Property accessors</a></li>
 <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code> / <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code></li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">Method definitions</a></li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li>
</ul>