blob: c891c2d4a425dbc84baa24f24cf3c82ed507dc1b (
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
|
---
title: Object.prototype.__proto__
slug: Web/JavaScript/Reference/Global_Objects/Object/proto
tags:
- Deprecated
- ECMAScript 2015
- JavaScript
- Object
- Property
- Prototype
- Reference
translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto
---
<div>{{JSRef}}{{Deprecated_header}}
<div class="blockIndicator warning">
<p><strong>警告:</strong> オブジェクトの <code>[[Prototype]]</code> を変更することは、最新の JavaScript エンジンがプロパティアクセスを最適化する仕組み上、<strong><em>すべての</em></strong>ブラウザーや JavaScript エンジンにおいて、とても低速な操作となります。プロトタイプの継承関係を変更することによる性能上の影響は微細で広範囲にわたり、単に <code>obj.__proto__ = ...</code> という文の実行時間に留まらず、 <code>[[Prototype]]</code> が変更された<strong><em>いずれかの</em></strong>オブジェクトへのアクセスを持つ<strong><em>あらゆる</em></strong>コードに及ぶ可能性があります。性能を気にしている場合、オブジェクトの <code>[[Prototype]]</code> の変更は避けるべきです。代わりに、 {{JSxRef("Object.create()")}} を使用して意図する <code>[[Prototype]]</code> をもつオブジェクトを新たに生成してください。</p>
</div>
<div class="blockIndicator warning">
<p><strong>警告:</strong> <code>Object.prototype.__proto__</code> は現時点でほとんどのブラウザーが対応していますが、そのプロパティの存在と正確な動作は、ウェブブラウザーの互換性を確保するためのレガシー機能として、 ECMAScript 2015 で初めて標準化されました。代わりに {{JSxRef("Object.getPrototypeOf()")}} を使用してください。</p>
</div>
</div>
<p>{{JSxRef("Object.prototype")}} の <code>__proto__</code> プロパティは、アクセスされるオブジェクトの内部の <code>[[Prototype]]</code> (オブジェクトまたは {{JSxRef("Global_Objects/null", "null")}} のどちらか) を暴露するアクセサプロパティ (ゲッター関数とセッター関数) です。</p>
<p><code>__proto__</code> の使用は、論争の的になり、推奨されていません。もともと ECMAScript 言語仕様には含まれていませんでしたが、現在のブラウザーでは結局それを実装しています。最近になって、 <code>__proto__</code> プロパティはウェブブラウザー間の互換性を保つために ECMAScript2015 の仕様で標準化されたので、将来的には対応されることになります。これは非推奨扱いで、代わりに {{JSxRef("Object.getPrototypeOf")}}/{{JSxRef("Reflect.getPrototypeOf")}} および {{JSxRef("Object.setPrototypeOf")}}/{{JSxRef("Reflect.setPrototypeOf")}} を推奨しています (とはいえ、オブジェクトの <code>[[Prototype]]</code> の設定は、性能が気になる場合には避けるべき低速の操作ですが)。</p>
<p>また、<code>__proto__</code> プロパティは、生成時に <code>[[Prototype]]</code> オブジェクトを設定するために {{JSxRef("Object.create()")}} の代わりとしてもオブジェクトリテラルの定義で使用されます。参照: <a href="/docs/Web/JavaScript/Reference/Operators/Object_initializer">オブジェクト初期化子</a></p>
<h2 id="Description" name="Description">解説</h2>
<p><code>__proto__</code> ゲッター関数はオブジェクトの内部の <code>[[Prototype]]</code> の値を外部に公開します。オブジェクトリテラルを使用して生成されたオブジェクトでは、この値は {{JSxRef("Object.prototype")}} です。配列リテラルを使用して生成されたオブジェクトでは、この値は {{JSxRef("Array.prototype")}} です。関数では、この値は {{JSxRef("Function.prototype")}} です。 <code>new fun</code> を使用して生成されたオブジェクトでは、 <code>fun</code> が JavaScript の ({{JSxRef("Array")}}、{{JSxRef("Boolean")}}、{{JSxRef("Date")}}、 {{JSxRef("Number")}}、 {{JSxRef("Object")}}、 {{JSxRef("String")}} などによって提供された内蔵コンストラクター関数のうちの一つである場合は — JavaScript の進化によって追加された新しいコンストラクタを含みます)、この値は常に <code>fun.prototype</code> です。 <code>new fun</code> を使用して生成されたオブジェクトでは、 <code>fun</code> がスクリプトで定義された関数である場合、この値は常に <code>fun.prototype</code> の値です。 (すなわち、コンストラクターがほかのオブジェクトを明示的に返さない場合、または <code>fun.prototype</code> に再代入されていない場合)。</p>
<p><code>__proto__</code> のセッターでオブジェクトの <code>[[Prototype]]</code> を変更することができます。オブジェクトは、 {{JSxRef("Object.isExtensible()")}} に応じて拡張可能である必要があります。拡張可能ではない場合、 {{JSxRef("Global_Objects/TypeError", "TypeError")}} が発生します。与えられた値はオブジェクト、または {{JSxRef("Global_Objects/null", "null")}} である必要があります。他の値が与えられた場合は何もしません。</p>
<p>プロトタイプが継承のためにどのように使用されるかを理解するには、ガイド記事の<a href="/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">継承とプロトタイプチェーン</a>を参照してください。</p>
<p><code>__proto__</code> プロパティは、ゲッター関数とセッター関数からなる {{JSxRef("Object.prototype")}} 上の簡単なアクセサープロパティです。最終的にの {{JSxRef("Object.prototype")}} を参照する <code>__proto__</code> に対してのプロパティアクセスはこのプロパティを探します。しかし、 {{JSxRef("Object.prototype")}} を参照しないアクセスはこのプロパティを探しません。 {{JSxRef("Object.prototype")}} が参照される前にいくつかの他の <code>__proto__</code> プロパティが見つけられた場合、そのプロパティは、 {{JSxRef("Object.prototype")}} 上で見つけられたプロパティを隠します。</p>
<h2 id="Examples" name="Examples">例</h2>
<h3 id="Using___proto__" name="Using___proto__">__proto__ の使用</h3>
<pre class="brush: js notranslate">var Circle = function () {};
var shape = {};
var circle = new Circle();
// Set the object prototype.
// 非推奨。 参考用です。 実際のコードで使用しないでください。
shape.__proto__ = circle;
// オブジェクトのプロトタイプを取得します。
console.log(shape.__proto__ === circle); // true
var shape = function () {};
var p = {
a: function () {
console.log('aaa');
}
};
shape.prototype.__proto__ = p;
var circle = new shape();
circle.a(); // aaa
console.log(shape.prototype === circle.__proto__); // true
// or
var shape = function () {};
var p = {
a: function () {
console.log('a');
}
};
var circle = new shape();
circle.__proto__ = p;
circle.a(); // a
console.log(shape.prototype === circle.__proto__); // false
// or
function test() {};
test.prototype.myname = function () {
console.log('myname');
};
var a = new test();
console.log(a.__proto__ === test.prototype); // true
a.myname(); // myname
// or
var fn = function () {};
fn.prototype.myname = function () {
console.log('myname');
};
var obj = {
__proto__: fn.prototype
};
obj.myname(); // myname
</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-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<p>{{Compat("javascript.builtins.Object.proto")}}</p>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li>{{JSxRef("Object.prototype.isPrototypeOf()")}}</li>
<li>{{JSxRef("Object.getPrototypeOf()")}}</li>
<li>{{JSxRef("Object.setPrototypeOf()")}}</li>
</ul>
|