diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
| commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
| tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/javascript/reference/global_objects/object/create | |
| parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
| download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip | |
initial commit
Diffstat (limited to 'files/ja/web/javascript/reference/global_objects/object/create')
| -rw-r--r-- | files/ja/web/javascript/reference/global_objects/object/create/index.html | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/files/ja/web/javascript/reference/global_objects/object/create/index.html b/files/ja/web/javascript/reference/global_objects/object/create/index.html new file mode 100644 index 0000000000..f59ce00141 --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/object/create/index.html @@ -0,0 +1,404 @@ +--- +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> +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</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> |
