つらい
B extends A ならnew B().__proto__ってBじゃないの
JSの詳細わからんけど、継承ツリーを作るという観点だとB.fooが存在しないときにB.__proto__.fooを試すから継承できる!wなのでAが入っていてほしそう(そうじゃない実装もありえるけど……)
プロトタイプ=インスタンスだと思うとnew B()はBの特異クラスを作ってるという見方もできるので、そういう観点だとB.__proto__はAだけどnew B().__proto__はBになって欲しいかもしれない。実際にES2015(以降)がどう考えてるのかは知らない
ECMA仕様によると、new B().__proto__はB.prototypeと同じもの。B.prototypeは
・B.prototype.__proto__ == A.prototype
・B.prototype.constructorはBのコンストラクタ
・B.prototypeはclass B {} のbodyで宣言されたメソッドを全てもつ
オブジェクトで、これはBの特異クラスとでも言うべき存在。Bという名前にバインドされているオブジェクトそのものではない(それはコンストラクタなので)
a.__proto__ == A.prototypeであることをもって「aの型はAである」というのであれば、new B().__proto__の型はAになる。が、new B().__proto__の中身は「class Bの宣言に書いてあるもの」に近い
「B.prototypeはBの特異クラスっぽいもの」は嘘っぽいな。一回作られたら変わらないので。「Bはメタ情報とコンストラクタを持ってるオブジェクト」「B.prototypeはフィールド一覧(メソッドも含む)」かな
久しぶりにECMAScript language specification読んだけどやっぱりよくできてるなあ
Nominal Typingとの対比でプロトタイプベースの継承(少なくとも__proto__を使ったセマンティクス)を考えると、__proto__が「インスタンスの型」を表すのか「親クラスの型」を表すのか判然としなくてハマるっぽいな