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
|
---
title: Object.create()
slug: Web/JavaScript/Reference/Global_Objects/Object/create
tags:
- ECMAScript 5
- JavaScript
- Method
- 'Null'
- Object
- Reference
- polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Object/create
---
<p>{{JSRef}}</p>
<p><code><strong>Object.create()</strong></code> メソッドは、既存のオブジェクトを新しく生成されるオブジェクトのプロトタイプとして使用して、新しいオブジェクトを生成します。</p>
<div>{{EmbedInteractiveExample("pages/js/object-create.html", "taller")}}</div>
<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div>
<h2 id="Syntax" name="Syntax">構文</h2>
<pre class="syntaxbox notranslate">Object.create(<var>proto</var>, [<var>propertiesObject</var>])</pre>
<h3 id="Parameters" name="Parameters">引数</h3>
<dl>
<dt><code><var>proto</var></code></dt>
<dd>新たに生成されるオブジェクトのプロトタイプになるべきオブジェクトです。</dd>
<dt><code><var>propertiesObject</var></code> {{Optional_inline}}</dt>
<dd>指定されていて、 {{jsxref("undefined")}} でない場合、それ自身が所有する一連の列挙可能なプロパティ (つまり、それ自身に定義されていて、プロトタイプチェインの中では<em>列挙可能でない</em>プロパティ) が、それらのプロパティ名を伴う一連のプロパティ記述子を指定し、新たに生成されるオブジェクトに追加されることになります。これらのプロパティは、 {{jsxref("Object.defineProperties()")}} の2番目の引数に対応するものです。</dd>
</dl>
<h3 id="Return_value" name="Return_value">返値</h3>
<p>指定したプロトタイプオブジェクトとプロパティを持つ新しいオブジェクトです。</p>
<h3 id="Exceptions" name="Exceptions">例外</h3>
<p><code><var>proto</var></code> 引数は次のいずれかになります。</p>
<ul>
<li>{{jsxref("null")}} または</li>
<li>{{jsxref("Object")}} ただし<a href="/ja/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript">プリミティブラッパーオブジェクト</a>を除く</li>
</ul>
<p><code>proto</code> がどちらでもない場合、 {{jsxref("TypeError")}} がスローされます。</p>
<h2 id="Custom_and_Null_objects" name="Custom_and_Null_objects">カスタムオブジェクトと Null オブジェクト</h2>
<p>完全にカスタムされたオブジェクトから作成された新しいオブジェクト (特に <code>null</code> オブジェクトから作成されたもの、基本的にはメンバーを持たないカスタムオブジェクト) は、予想外の振る舞いをすることがあります。これは特にデバッグ時に当てはまります。一般的なオブジェクト-プロパティ変換/検出ユーティリティ関数はエラーを生成したり、単に情報を失ったりする可能性があるからです (特にエラーを無視するサイレントエラートラップを使用している場合)。例えば、ここに二つのオブジェクトがあります。</p>
<pre class="brush: js notranslate">oco = Object.create( {} ); // create a normal object
ocn = Object.create( null ); // create a "null" object
> console.log(oco) // {} -- Seems normal
> console.log(ocn) // {} -- Seems normal here too, so far
oco.p = 1; // create a simple property on normal obj
ocn.p = 0; // create a simple property on "null" obj
> console.log(oco) // {p: 1} -- Still seems normal
> console.log(ocn) // {p: 0} -- Still seems normal here too. BUT WAIT...
</pre>
<p>上記のように、今のところすべてが正常なように見えます。しかし、実際に使ってみると、その違いはすぐに明らかになります。</p>
<pre class="brush: js notranslate">> "oco is: " + oco // shows "oco is: [object Object]"
> "ocn is: " + ocn // throws error: Cannot convert object to primitive value
</pre>
<p>多くの最も基本的な組み込み機能のほんの一部をテストするだけで、問題の大きさがより明確にわかります。</p>
<pre class="brush: js notranslate">> alert(oco) // shows [object Object]
> alert(ocn) // throws error: Cannot convert object to primitive value
> oco.toString() // shows [object Object]
> ocn.toString() // throws error: ocn.toString is not a function
> oco.valueOf() // shows {}
> ocn.valueOf() // throws error: ocn.valueOf is not a function
> oco.hasOwnProperty("p") // shows "true"
> ocn.hasOwnProperty("p") // throws error: ocn.hasOwnProperty is not a function
> oco.constructor // shows "Object() { [native code] }"
> ocn.constructor // shows "undefined"
</pre>
<p>このように、これらの違いにより、一見単純そうに見える問題であっても、デバッグがすぐに迷走してしまうことがあります。例えば、以下のようなものです。</p>
<p><em>シンプルな共通デバッグ関数です。</em></p>
<pre class="brush: js notranslate">// display top-level property name:value pairs of given object
function ShowProperties(obj){
for(var prop in obj){
console.log(prop + ": " + obj[prop] + "\n" );
}
}</pre>
<p><em>このような単純な結果ではありません。 (特にサイレントエラートラップがエラーメッセージを隠していた場合)</em></p>
<pre class="brush: js notranslate">ob={}; ob.po=oco; ob.pn=ocn; // create a compound object using the test objects from above as property values
> ShowProperties( ob ) // display top-level properties
- po: [object Object]
- Error: Cannot convert object to primitive value
Note that only first property gets shown.
</pre>
<p><em>(しかし、同じオブジェクトが単に順番が違うだけで作成されている場合 -- 少なくともいくつかの実装では...)</em></p>
<pre class="brush: js notranslate">ob={}; ob.pn=ocn; ob.po=oco; // create same compound object again, but create same properties in different order
> ShowProperties( ob ) // display top-level properties
- Error: Cannot convert object to primitive value
Note that neither property gets shown.</pre>
<p>Note that such a different order may arise statically via disparate fixed codings such as here, but also dynamically via whatever the order any such property-adding code-branches actually get executed at runtime as depends on inputs and/or random-variables. Then again, the actual iteration order is not guaranteed no matter what the order members are added.</p>
<p>Be aware of, also, that using Object.entries() on an object created via Object.create() will result in an empty array being returned.</p>
<pre class="brush: js notranslate">var obj = Object.create({ a: 1, b: 2 });
> console.log(Object.entries(obj)); // shows "[]"
</pre>
<h4 id="Some_NON-solutions">Some NON-solutions</h4>
<p>A good solution for the missing object-methods is not immediately apparent.</p>
<p>Adding the missing object-method directly from the standard-object does NOT work:</p>
<pre class="brush: js notranslate">ocn = Object.create( null ); // create "null" object (same as before)
ocn.toString = Object.toString; // since new object lacks method then try assigning it directly from standard-object
<span>> ocn.toString // shows "toString() { [native code] }" -- missing method seems to be there now</span>
> ocn.toString == Object.toString // shows "true" -- method seems to be same as the standard object-method
> ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function
</pre>
<p><br>
Adding the missing object-method directly to new object's "prototype" does not work either, since the new object does not have a real prototype (which is really the cause of ALL these problems) and one cannot be <strong>directly</strong> added:</p>
<pre class="brush: js notranslate">ocn = Object.create( null ); // create "null" object (same as before)
ocn.prototype.toString = Object.toString; // Error: Cannot set property 'toString' of undefined
ocn.prototype = {}; // try to create a prototype
ocn.prototype.toString = Object.toString; // since new object lacks method then try assigning it from standard-object <span>
> ocn.toString() // error: ocn.toString is not a function</span>
</pre>
<p><br>
Adding the missing object-method by using the standard-object<strong> </strong>as new object's prototype does not work either:</p>
<pre class="brush: js notranslate">ocn = Object.create( null ); // create "null" object (same as before)
Object.setPrototypeOf(ocn, Object); // set new object's prototype to the standard-object
> ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function
</pre>
<h4 id="Some_OK_solutions">Some OK solutions</h4>
<p>Again, adding the missing object-method directly from the <strong>standard-object </strong>does NOT work. However, adding the <strong>generic</strong> method directly, DOES:</p>
<pre class="brush: js notranslate">ocn = Object.create( null ); // create "null" object (same as before)
ocn.toString = toString; // since new object lacks method then assign it directly from generic version
> ocn.toString() // shows "[object Object]"
> "ocn is: " + ocn // shows "ocn is: [object Object]"
ob={}; ob.pn=ocn; ob.po=oco; // create a compound object (same as before)
> ShowProperties(ob) // display top-level properties
- po: [object Object]
- pn: [object Object]
</pre>
<p>However, setting the generic <strong>prototype</strong> as the new object's prototype works even better:</p>
<pre class="brush: js notranslate">ocn = Object.create( null ); // create "null" object (same as before)
Object.setPrototypeOf(ocn, Object.prototype); // set new object's prototype to the "generic" object (NOT standard-object)
</pre>
<p><em>(In addition to all the string-related functions shown above, this also adds:)</em></p>
<pre class="brush: js notranslate">> ocn.valueOf() // shows {}
> ocn.hasOwnProperty("x") // shows "false"
> ocn.constructor // shows "Object() { [native code] }"
// ...and all the rest of the properties and methods of Object.prototype.
</pre>
<p>As shown, objects modified this way now look very much like ordinary objects.</p>
<h2 id="Polyfill" name="Polyfill">ポリフィル</h2>
<p>このポリフィルは、プロトタイプは選択されたが第二引数を考慮しない状況向けに、新規オブジェクトを生成する主要な利用法に対応します。</p>
<p>実際の ES5 の <code>Object.create</code> では、<code>[[Prototype]]</code> として <code>null</code> を設定することがサポートされていますが、このポリフィルは ECMAScript5 以前のサポートをする制約上、null を使用できないことに注意してください。</p>
<pre class="brush: js notranslate"> if (typeof Object.create !== "function") {
Object.create = function (proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object: ' + proto);
} else if (proto === null) {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
if (typeof propertiesObject != 'undefined') {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
}
function F() {}
F.prototype = proto;
return new F();
};
}
</pre>
<h2 id="Examples" name="Examples">例</h2>
<h3 id="Classical_inheritance_with_Object.create" name="Classical_inheritance_with_Object.create"><code>Object.create()</code> を用いた古典的な継承</h3>
<p>以下の例は、古典的な継承をするための <code>Object.create()</code> の使用方法です。これは、すべての JavaScript が対応している単一継承です。</p>
<pre class="brush: js notranslate">// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
//If you don't set Rectangle.prototype.constructor to Rectangle,
//it will take the prototype.constructor of Shape (parent).
//To avoid that, we set the prototype.constructor to Rectangle (child).
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?', rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
</pre>
<p>複数のオブジェクトから継承したい場合は、ミックスインが可能です。</p>
<pre class="brush: js notranslate">function MyClass() {
SuperClass.call(this);
OtherSuperClass.call(this);
}
// inherit one class
MyClass.prototype = Object.create(SuperClass.prototype);
// mixin another
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// re-assign constructor
MyClass.prototype.constructor = MyClass;
MyClass.prototype.myMethod = function() {
// do something
};
</pre>
<p>{{jsxref("Object.assign()")}} は OtherSuperClass プロトタイプから MyClass プロトタイプへプロパティをコピーし、 MyClass のすべてのインスタンスで利用できるようにします。 <code>Object.assign()</code> は ES2015 で導入され、<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill">ポリフィルを利用することができます</a>。古いブラウザーへの対応が必要な場合は、 <code><a href="https://api.jquery.com/jQuery.extend/">jQuery.extend()</a></code> または <code><a href="https://lodash.com/docs/#assign">_.assign()</a></code> を利用することができます。</p>
<h3 id="Using_propertiesObject_argument_with_Object.create" name="Using_propertiesObject_argument_with_Object.create">Object.create() と propertiesObject 引数の併用</h3>
<pre class="brush: js notranslate">var o;
// プロトタイプを null にしてオブジェクトを生成
o = Object.create(null);
o = {};
// is equivalent to:
o = Object.create(Object.prototype);
// Example where we create an object with a couple of
// sample properties. (Note that the second parameter
// maps keys to *property descriptors*.)
o = Object.create(Object.prototype, {
// foo is a regular 'value property'
foo: {
writable: true,
configurable: true,
value: 'hello'
},
// bar is a getter-and-setter (accessor) property
bar: {
configurable: false,
get: function() { return 10; },
set: function(value) {
console.log('Setting `o.bar` to', value);
}
/* with ES2015 Accessors our code can look like this
get() { return 10; },
set(value) {
console.log('Setting `o.bar` to', value);
} */
}
});
function Constructor() {}
o = new Constructor();
// is equivalent to:
o = Object.create(Constructor.prototype);
// Of course, if there is actual initialization code
// in the Constructor function,
// the Object.create() cannot reflect it
// Create a new object whose prototype is a new, empty
// object and add a single property 'p', with value 42.
o = Object.create({}, { p: { value: 42 } });
// by default properties ARE NOT writable,
// enumerable or configurable:
o.p = 24;
o.p;
// 42
o.q = 12;
for (var prop in o) {
console.log(prop);
}
// 'q'
delete o.p;
// false
// to specify an ES3 property
o2 = Object.create({}, {
p: {
value: 42,
writable: true,
enumerable: true,
configurable: true
}
});
/* is not equivalent to:
This will create an object with prototype : {p: 42 }
o2 = Object.create({p: 42}) */
</pre>
<h2 id="Specifications" name="Specifications">仕様書</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ESDraft', '#sec-object.create', 'Object.create')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<div>
<p>{{Compat("javascript.builtins.Object.create")}}</p>
</div>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li>{{jsxref("Object.defineProperty()")}}</li>
<li>{{jsxref("Object.defineProperties()")}}</li>
<li>{{jsxref("Object.prototype.isPrototypeOf()")}}</li>
<li>{{jsxref("Reflect.construct()")}}</li>
<li><a href="http://ejohn.org/blog/objectgetprototypeof/">getPrototypeOf()</a> に関する John Resig 氏の投稿</li>
</ul>
|